代码之家  ›  专栏  ›  技术社区  ›  Coincoin

TreeView所有者在选择时绘制问题

  •  4
  • Coincoin  · 技术社区  · 14 年前

    我正在尝试向标准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中。

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

    1 回复  |  直到 8 年前
        1
  •  3
  •   Jason D Elon Zito    14 年前

    变化

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

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

    这在Vista X64和与2008年的.NET 3.5上起作用。让我知道它是否适合你。

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

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

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