4

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

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

这就是我正在做的事情:我用 .init 初始化,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 中。

有没有办法解决这种奇怪的行为?

4

1 回答 1

3

改变

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。请让我知道这对你有没有用。

我在观察默认窗口行为时观察到的是,在选择节点并获得焦点之前,不会绘制文本和突出显示。所以我检查了焦点条件以更改文本颜色。然而,这并不能精确地模仿寡妇行为,在鼠标释放之前不使用新颜色。当它选择在所有者绘制模式下绘制蓝色突出显示状态时,它出现了这一点,而不是在窗口绘制它时......这无疑是令人困惑的。

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

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);
    }
}
于 2010-03-10T21:18:00.320 回答