C# Ownerdrawn树视图(WinForms)

C# Ownerdrawn树视图(WinForms),c#,winforms,treeview,custom-controls,ownerdrawn,C#,Winforms,Treeview,Custom Controls,Ownerdrawn,我有一个带有复选框的TreeView控件,它是完全由所有者绘制的(DrawMode=TreeView-DrawMode.OwnerDrawAll) 我试图做的是让所有者绘制复选框,这样它们就可以有一个灰色状态。我正在为此使用VisualStyleRenderer 当我必须将展开/折叠图示符和复选框正确放置在项目边界中时,问题就出现了,因为图示符和复选框的“命中测试区域”似乎都是未知的且不可更改的 有没有办法获取这些区域的边界,或者用自定义值替换默认值?我遇到了同样的问题。必须将图形偏移适当的量,

我有一个带有复选框的TreeView控件,它是完全由所有者绘制的(
DrawMode=TreeView-DrawMode.OwnerDrawAll

我试图做的是让所有者绘制复选框,这样它们就可以有一个灰色状态。我正在为此使用
VisualStyleRenderer

当我必须将展开/折叠图示符和复选框正确放置在项目边界中时,问题就出现了,因为图示符和复选框的“命中测试区域”似乎都是未知的且不可更改的


有没有办法获取这些区域的边界,或者用自定义值替换默认值?

我遇到了同样的问题。必须将图形偏移适当的量,这是可以预测的

这里可能比您需要的更多,但这是我在日历控件旁边使用的自定义树的绘图:

private void TreeViewControl_DrawNode(Object sender, DrawTreeNodeEventArgs e)
{
    //What might seem like strange positioning/offset is to ensure that our custom drawing falls in
    //  line with where the base drawing would appear.  Otherwise, click handlers (hit tests) fail 
    //  to register properly if our custom-drawn checkbox doesn't fall within the expected coordinates.

    Int32 boxSize = 16;
    Int32 offset = e.Node.Parent == null ? 3 : 21;
    Rectangle bounds = new Rectangle(new Point(e.Bounds.X + offset, e.Bounds.Y + 1), new Size(boxSize, boxSize));
    ControlPaint.DrawCheckBox(e.Graphics, bounds, e.Node.Checked ? ButtonState.Checked : ButtonState.Normal);
    if (e.Node.Parent != null)
    {
        Color c = Color.Black;
        String typeName = e.Node.Name.Remove(0, 4);
        Object o = Enum.Parse(typeof(CalendarDataProvider.CalendarDataItemType), typeName);
        if (o != null && (o is CalendarDataProvider.CalendarDataItemType))
            c = CalendarDataProvider.GetItemTypeColor((CalendarDataProvider.CalendarDataItemType)o);
        bounds = new Rectangle(new Point(bounds.X + boxSize + 2, e.Bounds.Y + 1), new Size(13, 13));
        using (SolidBrush b = new SolidBrush(c))
            e.Graphics.FillRectangle(b, bounds);
        e.Graphics.DrawRectangle(Pens.Black, bounds);
        e.Graphics.DrawLine(Pens.Black, new Point(bounds.X + 1, bounds.Bottom + 1), new Point(bounds.Right + 1, bounds.Bottom + 1));
        e.Graphics.DrawLine(Pens.Black, new Point(bounds.Right + 1, bounds.Y + 1), new Point(bounds.Right + 1, bounds.Bottom + 1));
    }
    Font font = new Font("Microsoft Sans Serif", 9f, e.Node.Parent == null ? FontStyle.Bold : FontStyle.Regular);
    bounds = new Rectangle(new Point(bounds.X + boxSize + 2, e.Bounds.Y), new Size(e.Bounds.Width - offset - 2, boxSize));
    e.Graphics.DrawString(e.Node.Text, font, Brushes.Black, bounds);
}

您好,谢谢您的回复!事实上,现在我在做你的代码。我想知道是否可以在运行时读取
boxSize
offset
值(即,使用一些Win32 API),因为我担心将来这些值可能会更改,我的UI会以某种方式损坏……我之所以这样做是因为我觉得安全。基本控件不太可能以这种方式更改,因为它是Win32的基础。你可能会得到它,但我怀疑它是否值得这么麻烦