简体   繁体   English

TransformToAncestor给我错误的变换

[英]TransformToAncestor giving me the wrong transform

I'm new to WPF so this may be a newbie question. 我是WPF的新手,所以这可能是一个新手问题。 I'm working on some kind of diagram editor, and want to connect some elements with lines. 我正在某种图表编辑器上工作,并且想用线连接一些元素。 Some of these elements will be nested inside other elements, and a single line may pass over elements in different levels. 这些元素中的某些元素将嵌套在其他元素中,并且单行可能会越过不同级别的元素。 So what I want to do is draw these lines in the OnRender event in the top parent element. 因此,我要在顶层父元素的OnRender事件中绘制这些线。 Here is a preliminary attempt, where instead of lines I'm using squares around buttons, just to make sure I'm able to properly locate the child elements: 这是一个初步的尝试,在这里我不是在线条上而是在按钮周围使用正方形,只是为了确保能够正确定位子元素:

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

But this the result I get: 但这我得到的结果是:

在此处输入图片说明

If I replace element.TransformToAncestor(parent).TransformBounds(LayoutInformation.GetLayoutSlot(element)) with LayoutInformation.GetLayoutSlot(element) in the GetRect method, It'll look the way is supposed to, but only because the drawing happens to occur in the direct parent of the buttons. 如果我在GetRect方法element.TransformToAncestor(parent).TransformBounds(LayoutInformation.GetLayoutSlot(element))替换为LayoutInformation.GetLayoutSlot(element) ,则看起来应该是这样,但这仅是因为绘图发生在按钮的直接父级。 In my actual application the direct parent won't be doing the drawing, so I need to be able to get the slot relative to any arbitrary parent. 在我的实际应用程序中,直接父级不会绘制图形,因此我需要能够相对于任意父级获取插槽。

OK I figured it out. 好,我知道了。 Since GetLayoutSlot gets the slot relative to the parent, and TransformToAncestor includes the relation from child to parent, it's doubling the distance from the child element to the parent. 由于GetLayoutSlot获取相对于父级的插槽,并且TransformToAncestor包括子级到父级的关系,因此它将子级元素到父级的距离增加了一倍。 So changing GetRect to get the ancestor from the element's parent fixes the problem: 因此,更改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);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM