c# - 选择时 TreeView 所有者绘制故障

标签 c# .net winforms treeview ownerdrawn

我正在尝试向标准 System.Windows.Forms.TreeView 控件的元素添加更多图标。

我的计划是只更改 TreeView 控件的标签区域,但它显示了一个奇怪的行为。如果我单击一个节点来选择它,当按下鼠标按钮时,背景会使用高亮颜色正确绘制。但是,在我释放鼠标按钮之前,文本是错误的未选择颜色。就好像 e.State 包含鼠标按钮按下和释放之间的错误状态。

这是我正在做的事情:我使用 this.DrawMode = TreeViewDrawMode.OwnerDrawText 进行初始化,然后使用 this.DrawNode += LayoutTreeView_DrawNode 注册我的事件处理程序。这是处理程序:

void LayoutTreeView_DrawNode(object sender, DrawTreeNodeEventArgs e)
{

    Color color = (e.State & TreeNodeStates.Selected) != 0 ?
        SystemColors.HighlightText : SystemColors.WindowText;

    TextFormatFlags flags = TextFormatFlags.Left | TextFormatFlags.SingleLine |
       TextFormatFlags.VerticalCenter | TextFormatFlags.EndEllipsis;

    TextRenderer.DrawText(e.Graphics, e.Node.Text, Font, e.Bounds, color, flags);
}

如果我将处理程序设置为其默认大小写...

void LayoutTreeView_DrawNode(object sender, DrawTreeNodeEventArgs e)
{
    e.DefaultDraw = true;
}

...同样的事情发生了,这很奇怪,因为 Windows 实际上正在绘制它。此行为出现在带有 .Net 3.5 的 Windows XP 中。

有什么办法可以解决这种奇怪的行为吗?

最佳答案

改变

Color color = (e.State & TreeNodeStates.Selected) != 0 ?
    SystemColors.HighlightText : SystemColors.WindowText;

Color color = (e.State & TreeNodeStates.Focused) != 0 ?
    SystemColors.HighlightText : SystemColors.WindowText;

这适用于带有 .Net 3.5 的 Vista x64 和 VS 2008。让我知道它是否适合您。

我在观察默认窗口行为时观察到的是,在选择节点并获得焦点之前,不会绘制文本和突出显示。所以我检查了聚焦条件以更改文本颜色。然而,这并不能精确地模仿 Widows 的行为,在这种行为中,直到松开鼠标才使用新颜色。当它选择在 ownerdrawn 模式下绘制蓝色高亮状态与在窗口绘制它时选择绘制蓝色高亮状态时,这似乎是一个关键点……这无疑是令人困惑的。

编辑 但是,当您创建自己的派生 TreeView 时,您可以完全控制何时绘制所有内容。

public class MyTreeView : TreeView
{
    bool isLeftMouseDown = false;
    bool isRightMouseDown = false;
    public MyTreeView()
    {
        DrawMode = TreeViewDrawMode.OwnerDrawText;
    }

    protected override void OnMouseDown(MouseEventArgs e)
    {
        TrackMouseButtons(e);
        base.OnMouseDown(e);
    }

    protected override void OnMouseUp(MouseEventArgs e)
    {
        TrackMouseButtons(e);
        base.OnMouseUp(e);
    }
    protected override void OnMouseMove(MouseEventArgs e)
    {
        TrackMouseButtons(e);
        base.OnMouseMove(e);
    }

    private void TrackMouseButtons(MouseEventArgs e)
    {
        isLeftMouseDown = e.Button == MouseButtons.Left;
        isRightMouseDown = e.Button == MouseButtons.Right;
    }

    protected override void OnDrawNode(DrawTreeNodeEventArgs e)
    {
        // don't call the base or it will goof up your display!
        // capture the selected/focused states
        bool isFocused = (e.State & TreeNodeStates.Focused) != 0;
        bool isSelected = (e.State & TreeNodeStates.Selected) != 0;
        // set up default colors.
        Color color = SystemColors.WindowText;
        Color backColor = BackColor;

        if (isFocused && isRightMouseDown)
        {
            // right clicking on a 
            color = SystemColors.HighlightText;
            backColor = SystemColors.Highlight;
        }
        else if (isSelected && !isRightMouseDown)
        {
            // if the node is selected and we're not right clicking on another node.
            color = SystemColors.HighlightText;
            backColor = SystemColors.Highlight;
        }

        using (Brush sb = new SolidBrush(backColor))
            e.Graphics.FillRectangle(sb,e.Bounds);

        TextFormatFlags flags = TextFormatFlags.Left | TextFormatFlags.SingleLine |
           TextFormatFlags.VerticalCenter | TextFormatFlags.EndEllipsis;

        TextRenderer.DrawText(e.Graphics, e.Node.Text, Font, e.Bounds, color, backColor, flags);
    }
}

关于c# - 选择时 TreeView 所有者绘制故障,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2412776/

相关文章:

c# - Concat 名字和姓氏 MVC5

c# - 文本冒险中的编码交互

c# - 秒表的数据绑定(bind)问题已过去

c# - DGV CellPainting 行为异常

c# - 跨域设置文件夹权限

c# - 使用 c#,如何执行 sql 用户函数并获取其返回值?

c# - 为什么枚举会这样?

c# - 如何在C#中修复此计时器刻度错误?

c# - 表单之间的交互-如何从另一个表单更改表单的控件?

c# - 如何将空图像添加到表格