Gretings。
我正在创建一个界面来编辑游戏场景。基本上它由具有嵌套条件和动作的事件组成。因此,我计划使用两个树视图 - 一个用于选择事件,另一个用于选择要编辑的事件中的条件/操作。
现在,您看,如果我选择一个事件(在左侧树视图中),然后尝试在右侧树视图中选择一些内容,则左侧树视图将停止显示蓝色选择矩形。这显然很糟糕,因为现在用户不知道他正在编辑哪个事件!
我发现保留某些关于当前选择的信息的唯一方法是使用SelectedImageIndex,但这只是一个不同的小图像。
在没有关注树视图时,有没有其他方法可以突出显示treenode?我知道我可以只使用Graphics.DrawRectangle或者其他东西,但是我听说绘图应该在Paint事件中完成而treeview没有绘制事件...所以我想如果我在失去焦点的情况下绘制它,然后拖动窗体在屏幕外或其他什么地方,它会被“删除”?
无论如何,请告诉我你是否有想法(除了使用单独的图标选择和未选择的treenode)
谢谢!
答案 0 :(得分:56)
您要找的是HideSelection
上的TreeView
属性。
来自MSDN:
获取或设置一个值,该值指示即使树视图丢失焦点,所选树节点是否仍保持突出显示。
链接:http://msdn.microsoft.com/en-us/library/system.windows.forms.treeview.hideselection.aspx
<强>代码:强>
TreeView.HideSelection = false;
答案 1 :(得分:16)
它仍然显示,但只有浅灰色,这取决于您的屏幕和当前设置可以在附近可见!
重写OnDrawNode事件。所以你创建了一个新类(称之为“SpecialTreeView”),这是继承自TreeView
之类的class 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);
}
}
}
。然后添加以下事件覆盖:
selectedColor
编译代码,您应该在设计器的工具箱中看到“SpecialTreeView”。使用相同的名称将TreeView替换为新的TreeView,唯一不同的是选择颜色。选中后,如果未选择deselectedColor
,则会{{1}}。
我希望这会有所帮助。
答案 2 :(得分:9)
快速解决方案:
设置属性:
HideSelection = false;
DrawMode = TreeViewDrawMode.OwnerDrawText;
然后在DrawNode事件处理程序中执行:
private void treeView1_DrawNode(object sender, DrawTreeNodeEventArgs e) {
e.DrawDefault = true;
}
在Windwos 7上,这将恢复旧的渲染,包括选择周围的虚线框(实际上看起来有点过时)。文本将是白色的焦点,黑色没有焦点。背景保持蓝色且可见。
这个答案不是新的,其他的也包含这些步骤,但这是最小的需要(至少在Windows 7中,没有测试其他操作系统)。
答案 3 :(得分:8)
不是绝对完美的解决方案,但非常接近:
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(e.X, e.Y);
if (node != null && node.Bounds.Contains(e.X, e.Y))
treeView.SelectedNode = node;
};
答案 4 :(得分:1)
类似于上一个,但外观更类似于Win10标准:
treeView.HideSelection = false;
treeView.DrawMode = TreeViewDrawMode.OwnerDrawText;
treeView.DrawNode += (o, e) =>
{
if (e.Node == e.Node.TreeView.SelectedNode)
{
Font font = e.Node.NodeFont ?? e.Node.TreeView.Font;
Rectangle r = e.Bounds;
r.Offset(0, 1);
Brush brush = e.Node.TreeView.Focused ? SystemBrushes.Highlight : Brushes.Gray;
e.Graphics.FillRectangle(brush, e.Bounds);
TextRenderer.DrawText(e.Graphics, e.Node.Text, font, r, SystemColors.HighlightText, TextFormatFlags.GlyphOverhangPadding);
}
else
e.DrawDefault = true;
};
treeView.MouseDown += (o, e) =>
{
TreeNode node = treeView.GetNodeAt(e.Location);
if (node != null && node.Bounds.Contains(e.Location)) treeView.SelectedNode = node;
};
答案 5 :(得分:0)
找到了一种更简单的方法:
private void treeViewBenutzerverwaltung_AfterSelect(object sender, TreeViewEventArgs e) { // Select new node e.Node.BackColor = SystemColors.Highlight; e.Node.ForeColor = SystemColors.HighlightText; if (_lastSelectedNode != null) { // Deselect old node _lastSelectedNode.BackColor = SystemColors.Window; _lastSelectedNode.ForeColor = SystemColors.WindowText; } lastSelectedNode = e.Node; }