C# WinForms在树视图没有焦点时突出显示树节点

x4shl7ld  于 7个月前  发布在  C#
关注(0)|答案(6)|浏览(76)

我在做一个界面来编辑游戏的场景。它基本上由事件组成,事件具有嵌套的条件和操作。因此,我计划使用两个树视图-一个用于选择事件,另一个用于选择事件中要编辑的条件/操作。
现在,你看,如果我选择一个事件(在左边的树视图中),然后试图选择右边的树视图中的东西,左边的树视图将停止显示蓝色的选择矩形。这显然是不好的,因为现在用户不知道他正在编辑哪个事件!
我发现的保留当前选择内容的信息的唯一方法是使用SelectedImageIndex,但这只是一个小图像。
在树视图上没有焦点时,有没有其他方法可以突出显示树节点?我知道我可以使用Graphics.DrawRectangle或其他东西,但我听说绘图应该在Paint事件中完成,而Treeview没有Paint事件。所以我猜如果我把它画在失去焦点的事件上,然后把表单从屏幕上拖出来,它会被“擦除”吗?
无论如何,请告诉我,如果你有一个想法(除了使用一个单独的图标为选定和未选定的树节点)。

qmb5sa22

qmb5sa221#

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

来自MSDN:

获取或设置一个值,该值指示即使树视图失去焦点,选定的树节点是否仍保持突出显示。
友情链接:http://msdn.microsoft.com/en-us/library/system.windows.forms.treeview.hideselection.aspx

验证码:

TreeView.HideSelection = false;
smdnsysy

smdnsysy2#

它仍然显示,但只有在浅灰色,这取决于您的屏幕和当前设置可以在可见附近!
停止OnDrawNode事件。因此,您创建了一个新类(称为“SpecialTreeView”),它继承自Microsoft 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);
        }
    }
}

编译代码后,您应该在设计器的工具箱中看到“SpecialTreeView”。使用相同的名称替换您的TreeView,唯一不同的是选择颜色。如果选择,则为selectedColor,如果未选择,则为deselectedColor
我希望这能帮上忙。

kwvwclae

kwvwclae3#

快速解决方案:

设置属性:

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

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

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

在Windwos 7上,这会恢复旧的渲染,包括选区周围的虚线框(实际上看起来有点过时)。文本将为带焦点的白色,无焦点的黑色。背景保持蓝色和可见。
这个答案并不新鲜,其他人也包含这些步骤,但这是最低限度的需要(至少在Windows 7中,没有测试其他操作系统)。

brjng4g3

brjng4g34#

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

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;
};
mccptt67

mccptt675#

找到一个更简单的方法:
1.设置TreeView.HideSelection = True

  1. decompose私有字段private TreeNode _lastSelectedNode = null;
    1.在TreeView.AfterSelect-Callback中添加以下内容:
private TreeNode _lastSelectedNode = null;
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;
}
v8wbuo2f

v8wbuo2f6#

与前一个类似,但外观更类似于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;
};

相关问题