3

カスタムPanelコントロールの論理的な子でDataContextChangedが発生しないという問題があります。私はそれをこれに絞り込みました:

ウィザードで生成されたWPFアプリケーションから始めて、次を追加します。

    private void Window_Loaded( object sender, RoutedEventArgs e )
    {
        var elt = new FrameworkElement();
        this.AddLogicalChild( elt );
        DataContext = 42;
        Debug.Assert( (int)elt.DataContext == 42 );
    }

私が理解しているように、DataContext継承可能な依存関係プロパティであるため、これは機能します。

ここで、ウィンドウ(this)とその論理子の両方にDataContextChangedのイベントハンドラーを追加します。

    this.DataContextChanged += 
        delegate { Debug.WriteLine( "this:DataContextChanged" ); };
    elt.DataContextChanged += 
        delegate { Debug.WriteLine( "elt:DataContextChanged" ); };

これを実行すると、最初のイベントハンドラーのみが実行されます。どうしてこれなの?AddLogicalChild(elt)の代わりに、次のようにします。

this.Content = elt;

両方のハンドラーが実行されます。しかし、これは私の場合のオプションではありません-視覚的な子ではないはずのFrameworkContentElementsをコントロールに追加しています。

何が起きてる?AddLogicalChild()以外に何かを実行して、機能させる必要がありますか?

(幸い、かなり単純な回避策があります。要素のDataContextをウィンドウのDataContextにバインドするだけです)

BindingOperations.SetBinding( elt, FrameworkElement.DataContextProperty, 
            new Binding( "DataContext" ) { Source = this } );

ありがとうございました。

4

2 に答える 2

7

LogicalChildrenプロパティもオーバーライドする必要があります。

protected override System.Collections.IEnumerator LogicalChildren
{
    get { yield return elt; }
}

もちろん、基本実装によって定義された論理的な子も返したいと思うでしょう。

于 2009-04-07T08:23:38.583 に答える