1

キャンバスに含まれる子の描画順序を決定する必要がありました。だから私はこのQ/Aに出くわしました:

同じ論理/ビジュアルツリーの一部である2つのWPFコントロールの相対的なZオーダーを比較するにはどうすればよいですか?

これはほとんどの場合完全に機能しますが、このコードからエラーが発生することがあります。

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)は、「値をnullにすることはできません」という例外をスローすることになります。

これが私がどのように使用するかの一例ですDrawOrderComparer

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

私の理論では、新しいコントロールで親が定義される前に並べ替えが行われています。これは、後で何らかのイベントによって設定されるためです。問題は、それがどのようなイベントであり、それを聞くことができるかどうかわからないことです。

誰かアイデアはありますか?

4

1 に答える 1

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

1回の呼び出しで複数の子を追加する場合があるため、メソッドはすべてのコントロールが読み込まれた後にのみ実行されます。エラーがなくなったので、うまくいけばそれが問題でした。

于 2012-11-15T00:32:58.310 に答える