2015-02-11 40 views
2

我是新來的WPF,所以這可能是一個新手問題。我正在研究某種圖編輯器,並希望用線連接一些元素。其中一些元素將嵌套在其他元素中,並且一行可能會跨越不同級別的元素。所以我想要做的是在頂部父元素中的OnRender事件中繪製這些行。這是一個初步的嘗試,我使用的按鈕周圍的廣場,其中線代替,只是爲了確保我能夠正確定位的子元素:TransformToAncestor給我錯誤的轉換

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

但這種結果我得到:

enter image description here

如果我在GetRectLayoutInformation.GetLayoutSlot(element)取代element.TransformToAncestor(parent).TransformBounds(LayoutInformation.GetLayoutSlot(element)),它會看的方式是應該的,但只是因爲繪製發生在按鈕的直接父發生。在我的實際應用程序中,直接父項不會執行繪圖,因此我需要能夠獲取相對於任意父項的槽。

回答

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