TreeNode选择BackColor,而TreeView没有聚焦

Spa*_*ark 23 c# treeview custom-draw winforms

在TreeView没有焦点的情况下,有一种简单的方法可以让选定的TreeNode保留其SystemColors.Highlight BackColor吗?因为即使将HideSelection设置为false,也几乎无法看到所选的BackColor.

TreeView具有焦点时选择的TreeNode:

重点

TreeView没有焦点时选择的TreeNode:

没有重点

提前致谢.

编辑:我知道我可以将DrawMode设置为OwnerDrawAll然后添加自定义DrawNode事件.我之前尝试过这个问题,我遇到的问题是我不知道如何正确地绘制TreeNode的相应ImageKey.

Iro*_*eek 13

如果保留SystemColors.Highlight背景颜色是你想要的,那么你不需要将TreeView's DrawMode属性设置为TreeViewDrawMode.OwnerDrawAll.设置它TreeViewDrawMode.OwnerDrawText应该足够了,因此你不必担心绘制TreeNode相应的ImageKey.

  1. 设置TreeView.DrawModeTreeViewDrawMode.OwnerDrawText:

    treeView.DrawMode = TreeViewDrawMode.OwnerDrawText;
    
    Run Code Online (Sandbox Code Playgroud)
  2. 设置Treview.HideSelectionfalse,以便节点状态将保持为选中状态:

    treeView.HideSelection= false;
    
    Run Code Online (Sandbox Code Playgroud)
  3. 添加DrawNode事件处理程序以使用SystemColors.Highlight颜色绘制背景:

    private void treeView_DrawNode(object sender, DrawTreeNodeEventArgs e)
    {
      if (e.Node == null) return;
    
      // if treeview's HideSelection property is "True", 
      // this will always returns "False" on unfocused treeview
      var selected = (e.State & TreeNodeStates.Selected) == TreeNodeStates.Selected;
      var unfocused = !e.Node.TreeView.Focused;
    
      // we need to do owner drawing only on a selected node
      // and when the treeview is unfocused, else let the OS do it for us
      if (selected && unfocused)
      {
        var font = e.Node.NodeFont ?? e.Node.TreeView.Font;
        e.Graphics.FillRectangle(SystemBrushes.Highlight, e.Bounds);
        TextRenderer.DrawText(e.Graphics, e.Node.Text, font, e.Bounds, SystemColors.HighlightText, TextFormatFlags.GlyphOverhangPadding);
      }
      else
      {
        e.DrawDefault = true;
      }
    }
    
    Run Code Online (Sandbox Code Playgroud)

  • 不幸的是,只有在FullRowSelect为false时才能正常工作,否则在选择时会出现奇怪的闪烁,然后只保留文本的背景,而不是整行. (4认同)

Spa*_*ark 13

解决方案,就像一个魅力:

public TreeNode previousSelectedNode = null;
private void treeView1_Validating(object sender, System.ComponentModel.CancelEventArgs e)
{
    treeView1.SelectedNode.BackColor = SystemColors.Highlight;
    treeView1.SelectedNode.ForeColor = Color.White;
    previousSelectedNode = treeView1.SelectedNode;
}

private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
{
    if(previousSelectedNode != null)
    {
        previousSelectedNode.BackColor = treeView1.BackColor;
        previousSelectedNode.ForeColor = treeView1.ForeColor;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 注意这只有在HideSelection为True(默认值)时才有效! (3认同)

Afr*_*din 8

我使用这个解决方案,它的效果更好

private void treeView1_Enter(object sender, EventArgs e)
{
   if (treeView1.SelectedNode != null)
   {
       treeView1.SelectedNode.BackColor = Color.Empty;
       treeView1.SelectedNode.ForeColor = Color.Empty;
   }
}

private void treeView1_Leave(object sender, EventArgs e)
{
   if (treeView1.SelectedNode != null)
   {
       treeView1.SelectedNode.BackColor = SystemColors.Highlight;
       treeView1.SelectedNode.ForeColor = Color.White;
   }
}
Run Code Online (Sandbox Code Playgroud)

编辑

基于文档,

默认为 Color.Empty

所以,treeView1_Enter最好像这样设置颜色

treeView1.SelectedNode.BackColor = Color.Empty;
treeView1.SelectedNode.ForeColor = Color.Empty;
Run Code Online (Sandbox Code Playgroud)

上一个答案

treeView1.SelectedNode.BackColor = treeView1.BackColor;
treeView1.SelectedNode.ForeColor = treeView1.ForeColor;
Run Code Online (Sandbox Code Playgroud)