2012-11-15 75 views
1

我需要確定畫布中包含的子項的繪製順序。在WPF Canvas.Children上查找繪畫順序問題

How to compare the relative Z order of two WPF controls that are part of the same logical/visual tree?

這完美的作品大部分時間,但有時我從該代碼得到一個錯誤:

private Panel FindWindowRoot(FrameworkElement child) 
{ 
    FrameworkElement current = child; 
    while(current as Window == null) 
    { 
     current = (FrameworkElement)VisualTreeHelper.GetParent(current); 
    } 
    return ((Window)current).Content as Panel; 
} 

呼叫VisualTreeHelper.GetParent(current)最終拋出一個異常,所以我碰到這個Q/A跑「價值不能爲空。」

下面是我如何使用DrawOrderComparer的一個示例。

ucVertexControl Control = new ucVertexControl(vertex); 
cnvDrawingArea.Children.Add(Control); 
SortedChildren = cnvDrawingArea.Children.OfType<FrameworkElement>().OrderByDescending(x => x, new Classes.DrawOrderComparer()).Cast<UIElement>().ToList(); 

我的理論是,排序發生在新的控件甚至有一個父定義,因爲它後來被某些事件設置。問題是我不知道是什麼事件,如果我可以聽。

任何人有任何想法?

回答

1

我相信我找到了解決方案。

我不知道任何會從畫布中觸發的事件,但我知道每個用戶控件都有一個Loaded事件。所以我改變了這一點:

ucVertexControl Control = new ucVertexControl(vertex); 
cnvDrawingArea.Children.Add(Control); 
SortedChildren = cnvDrawingArea.Children.OfType<FrameworkElement>().OrderByDescending(x => x, new Classes.DrawOrderComparer()).Cast<UIElement>().ToList(); 

要這樣:

ucVertexControl Control = new ucVertexControl(vertex); 
Control.Loaded += new RoutedEventHandler(Control_Loaded); 
cnvDrawingArea.Children.Add(Control); 

Control_Loaded功能只是轉身調用此方法:

private void UpdateSortedChildren() 
{ 
    if (cnvDrawingArea.Children.OfType<FrameworkElement>().Any(x => !x.IsLoaded)) return; 
    SortedChildren = cnvDrawingArea.Children.OfType<FrameworkElement>().OrderByDescending(x => x, new Classes.DrawOrderComparer()).Cast<UIElement>().ToList(); 
} 

因爲有些時候我加入多次兒童在一次調用中只會在所有控件加載後執行該方法。錯誤已經消失,所以希望這是問題。