当treeview没有焦点时,C#WinForms突出显示treenode

Gretings。

我正在创建一个界面来编辑游戏场景。 基本上它由具有嵌套条件和动作的事件组成。 因此,我计划使用两个树视图 – 一个用于选择事件,另一个用于选择要编辑的事件内的条件/操作。

现在,您看,如果我选择一个事件(在左侧树视图中),然后尝试在右侧树视图中选择一些内容,则左侧树视图将停止显示蓝色选择矩形。 这显然是不好的,因为现在用户不知道他正在编辑哪个事件!

我发现保留某些关于当前选择的信息的唯一方法是使用SelectedImageIndex,但这只是一个不同的小图像。

有没有其他方法可以突出显示treenode,而没有关注树视图? 我知道我可以只使用Graphics.DrawRectangle或者其他东西,但是我听说绘图应该在Paint事件中完成而treeview没有绘制事件…所以我想如果我在失去焦点的情况下绘制它,然后拖动窗体屏幕外的东西,它会被“删除”?

无论如何,请告诉我你是否有想法(除了使用一个单独的图标选择和未选择treenode)

谢谢!

您正在寻找的是TreeView上的HideSelection属性。

来自MSDN:

获取或设置一个值,该值指示即使树视图丢失焦点,所选树节点是否仍保持突出显示。

链接: http : //msdn.microsoft.com/en-us/library/system.windows.forms.treeview.hideselection.aspx

码:

 TreeView.HideSelection = false; 

它仍然显示,但只有浅灰色,这取决于您的屏幕和当前设置可以在附近可见!

覆盖OnDrawNode事件。 所以你创建和新类(称之为“SpecialTreeView”)inheritance自Microsoft TreeViewclass SpecialTreeView : TreeView 。 然后添加以下事件覆盖:

 protected override void OnDrawNode(DrawTreeNodeEventArgs e) { TreeNodeStates treeState = e.State; Font treeFont = e.Node.NodeFont ?? e.Node.TreeView.Font; // Colors. Color foreColor = e.Node.ForeColor; string strDeselectedColor = @"#6B6E77", strSelectedColor = @"#94C7FC"; Color selectedColor = System.Drawing.ColorTranslator.FromHtml(strSelectedColor); Color deselectedColor = System.Drawing.ColorTranslator.FromHtml(strDeselectedColor); // New brush. SolidBrush selectedTreeBrush = new SolidBrush(selectedColor); SolidBrush deselectedTreeBrush = new SolidBrush(deselectedColor); // Set default font color. if (foreColor == Color.Empty) foreColor = e.Node.TreeView.ForeColor; // Draw bounding box and fill. if (e.Node == e.Node.TreeView.SelectedNode) { // Use appropriate brush depending on if the tree has focus. if (this.Focused) { foreColor = SystemColors.HighlightText; e.Graphics.FillRectangle(selectedTreeBrush, e.Bounds); ControlPaint.DrawFocusRectangle(e.Graphics, e.Bounds, foreColor, SystemColors.Highlight); TextRenderer.DrawText(e.Graphics, e.Node.Text, treeFont, e.Bounds, foreColor, TextFormatFlags.GlyphOverhangPadding); } else { foreColor = SystemColors.HighlightText; e.Graphics.FillRectangle(deselectedTreeBrush, e.Bounds); ControlPaint.DrawFocusRectangle(e.Graphics, e.Bounds, foreColor, SystemColors.Highlight); TextRenderer.DrawText(e.Graphics, e.Node.Text, treeFont, e.Bounds, foreColor, TextFormatFlags.GlyphOverhangPadding); } } else { if ((e.State & TreeNodeStates.Hot) == TreeNodeStates.Hot) { e.Graphics.FillRectangle(SystemBrushes.Window, e.Bounds); TextRenderer.DrawText(e.Graphics, e.Node.Text, hotFont, e.Bounds, System.Drawing.Color.Black, TextFormatFlags.GlyphOverhangPadding); } else { e.Graphics.FillRectangle(SystemBrushes.Window, e.Bounds); TextRenderer.DrawText(e.Graphics, e.Node.Text, treeFont, e.Bounds, foreColor, TextFormatFlags.GlyphOverhangPadding); } } } 

编译代码,您应该在设计器的工具箱中看到“SpecialTreeView”。 使用相同的名称将TreeView替换为新的TreeView,唯一不同的是选择颜色。 选中时,它将被selectedColor ,当未选择deselectedColor

我希望这有帮助。

快速解决方案

设置属性:

  • HideSelection = false;
  • DrawMode = TreeViewDrawMode.OwnerDrawText;

然后在DrawNode事件处理程序中简单地执行:

 private void treeView1_DrawNode(object sender, DrawTreeNodeEventArgs e) { e.DrawDefault = true; } 

在Windwos 7上,这将恢复旧的渲染,包括选择周围的虚线框(实际上看起来有点过时)。 文本将是白色的焦点,黑色没有焦点。 背景保持蓝色且可见。

这个答案并不新鲜,其他的也包含这些步骤,但这是最小的需求(至少在Windows 7中,没有测试其他操作系统)。

不是绝对完美的解决方案,但非常接近:

 treeView.HideSelection = false; treeView.DrawMode = TreeViewDrawMode.OwnerDrawText; treeView.DrawNode += (o, e) => { if (!e.Node.TreeView.Focused && e.Node == e.Node.TreeView.SelectedNode) { Font treeFont = e.Node.NodeFont ?? e.Node.TreeView.Font; e.Graphics.FillRectangle(Brushes.Gray, e.Bounds); ControlPaint.DrawFocusRectangle(e.Graphics, e.Bounds, SystemColors.HighlightText, SystemColors.Highlight); TextRenderer.DrawText(e.Graphics, e.Node.Text, treeFont, e.Bounds, SystemColors.HighlightText, TextFormatFlags.GlyphOverhangPadding); } else e.DrawDefault = true; }; treeView.MouseDown += (o, e) => { TreeNode node = treeView.GetNodeAt(eX, eY); if (node != null && node.Bounds.Contains(eX, eY)) treeView.SelectedNode = node; };