如何在TreeView的每个节点旁边添加一个按钮?

ala*_*a27 7 .net c# treeview winforms

如何在TreeView的每个节点旁边添加一个按钮?

Mik*_*kis 12

在树视图的每个节点旁边添加一个按钮很困难.您必须自己处理树视图的绘制,并自己绘制按钮并模拟其功能,或创建子按钮控件并在树控件中的正确位置显示它们,然后在控件滚动时处理它们的重新定位等.无论哪种方式,它都将成为一场噩梦.

幸运的是,有一个简单的方法:你不必做任何复杂的事情,因为你不应该这样做!

你有没有见过带有按钮的树控件?不会.因此,如果您的树形控件中有按钮,则最终用户会将其视为奇怪的.

你应该做的是考虑其他应用程序如何解决你试图解决的问题,而不使用带有按钮的树形控件,并按照它们的方式执行.


小智 5

最简单的方法是自己画树。这是一个小例子(请注意 PushButtonState 位于 System.Windows.Forms.VisualStyles 命名空间内):

public class CustomTreeView : TreeView
{
    private Rectangle buttonRect = new Rectangle(80, 2, 50, 26);
    private StringFormat stringFormat;

    public CustomTreeView()
    {
        SetStyle(ControlStyles.OptimizedDoubleBuffer, true);

        DrawMode = TreeViewDrawMode.OwnerDrawText;
        ShowLines = false;
        FullRowSelect = true;
        ItemHeight = 30;

        stringFormat = new StringFormat();
        stringFormat.Alignment = StringAlignment.Near;
        stringFormat.LineAlignment = StringAlignment.Center;
    }

    protected override void OnDrawNode(DrawTreeNodeEventArgs e)
    {
        e.Graphics.DrawString(e.Node.Text, this.Font, new SolidBrush(this.ForeColor), e.Bounds, stringFormat);
        ButtonRenderer.DrawButton(e.Graphics, new Rectangle(e.Node.Bounds.Location + new Size(buttonRect.Location), buttonRect.Size), "btn", this.Font, true, (e.Node.Tag != null) ? (PushButtonState)e.Node.Tag : PushButtonState.Normal);
    }

    protected override void OnNodeMouseClick(TreeNodeMouseClickEventArgs e)
    {
        if (e.Node.Tag != null && (PushButtonState)e.Node.Tag == PushButtonState.Pressed)
        {
            e.Node.Tag = PushButtonState.Normal;
            MessageBox.Show(e.Node.Text + " clicked");
            // force redraw
            e.Node.Text = e.Node.Text;
        }
    }

    protected override void OnMouseDown(MouseEventArgs e)
    {
        TreeNode tnode = GetNodeAt(e.Location);
        if (tnode == null) return;

        Rectangle btnRectAbsolute = new Rectangle(tnode.Bounds.Location + new Size(buttonRect.Location), buttonRect.Size);
        if (btnRectAbsolute.Contains(e.Location))
        {
            tnode.Tag = PushButtonState.Pressed;
            tnode.Text = tnode.Text;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

此外,即使不创建自定义控件,您也可以实现这一点 - 只需将这些事件处理程序添加到标准 TreeView