我需要确定画布中包含的子画面的绘制顺序。所以我遇到了这个Q / A:
这在大多数情况下都能正常工作,但有时我会从此代码中收到错误:
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)
最终会抛出异常“值不能为空。”
以下是我如何使用DrawOrderComparer
。
ucVertexControl Control = new ucVertexControl(vertex);
cnvDrawingArea.Children.Add(Control);
SortedChildren = cnvDrawingArea.Children.OfType<FrameworkElement>().OrderByDescending(x => x, new Classes.DrawOrderComparer()).Cast<UIElement>().ToList();
我的理论是,在新控件甚至已定义父级之前进行排序,因为稍后某些事件会对其进行设置。问题是我不知道那是什么事,我是否可以听。
有人有什么想法吗?
答案 0 :(得分: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();
}
由于有时我在一次调用中添加多个子节点,因此只有在加载了所有控件后才会执行该方法。错误已经消失,所以希望这是问题所在。