我是WPF的新手,所以这可能是一个新手问题。我正在研究某种图表编辑器,并希望用线条连接一些元素。其中一些元素将嵌套在其他元素中,一行可以传递不同级别的元素。所以我想要做的是在顶部父元素的OnRender
事件中绘制这些行。这是一个初步的尝试,而不是我在按钮周围使用方块,只是为了确保我能够正确定位子元素:
public class Container : Border
{
public readonly StackPanel Panel = new StackPanel();
private readonly Pen _Pen = new Pen(Brushes.Red, 2);
public Container()
{
Panel.Orientation = Orientation.Vertical;
Panel.Children.Add(MakeButton("One"));
Panel.Children.Add(MakeButton("Two"));
Panel.Children.Add(MakeButton("Three"));
Child = Panel;
}
private Rect GetRect(Visual parent, FrameworkElement element)
{
return element.TransformToAncestor(parent).TransformBounds(LayoutInformation.GetLayoutSlot(element));
}
protected override void OnRender(DrawingContext dc)
{
base.OnRender(dc);
foreach (Button item in Panel.Children)
{
var box = GetRect(this, item);
dc.DrawRectangle(Brushes.Transparent, _Pen, box);
}
}
private static Button MakeButton(string text)
{
Button button = new Button();
button.Content = text;
button.Padding = new Thickness(10);
button.Margin = new Thickness(5);
return button;
}
}
但这是我得到的结果:
如果我在element.TransformToAncestor(parent).TransformBounds(LayoutInformation.GetLayoutSlot(element))
方法中将LayoutInformation.GetLayoutSlot(element)
替换为GetRect
,它看起来应该是这样的,但这只是因为绘图恰好发生在纽扣。在我的实际应用中,直接父节点不会进行绘制,所以我需要能够相对于任意父节点获取插槽。
答案 0 :(得分:0)
好的,我明白了。由于GetLayoutSlot
获取相对于父项的插槽,TransformToAncestor
包含从子项到父项的关系,因此它将子元素与父元素的距离加倍。因此,更改GetRect
以从元素的父级获取祖先可以解决问题:
private Rect GetRect(Visual ancestor, FrameworkElement element)
{
Visual parent = element.Parent as Visual;
var transform = parent.TransformToAncestor(ancestor);
var slot = LayoutInformation.GetLayoutSlot(element);
return new Rect(transform.Transform(slot.TopLeft), slot.Size);
}