3

私の WPF アプリケーションには、項目を選択するためのリストがあります。選択された項目は、その後の操作のために ContentControl に表示されます。選択した項目のタイプ (複数ある場合もあります) に応じて、適切な DataTemplate が ContentControl で使用されます。これまでのところ、これはデータ処理ビジネス アプリケーションでは珍しいことではありません。

各 DataTemplate には、値を ViewModel クラスの特定のプロパティにバインドする複数の TextBox およびその他のコントロールがあります。リストから別の項目を選択すると、これらすべてが期待どおりに更新されます。ボタンは、ViewModel の正しいインスタンスでコマンドも実行します。

コマンドも実行するコンテキスト メニュー項目が 1 つありますが、これは最初に選択した項目に対してのみ機能します。同じタイプの別の要素がリストから選択され、既に読み込まれているテンプレート ビューを再利用すると、コンテキスト メニューのコマンドは常に最初に選択されたアイテムに対して実行されます。そのため、バインディングは ViewModel の正しいインスタンスに更新されません。

メニュー項目で正しい ViewModel インスタンスを使用する唯一の方法は、異なるタイプの項目を選択して、テンプレートを別のビューに変更することです。そうして初めて、コンテキスト メニューが正しく更新されます。

ビュー内の他のバインドと同じように、メニュー項目コマンドが更新されないのはなぜですか? ロード時に一度フェッチされますが、ビューの存続期間中は更新されません。

4

1 に答える 1

5

更新されないのは Command バインディングではなく、古くなった DataContext です。そして、これは広く知られている問題です。適切な検索用語を知っていれば...

さらなるリンクを含む説明は次のとおりです。

http://www.codeproject.com/Articles/162784/WPF-ContextMenu-Strikes-Again-DataContext-Not-Upda

その記事の関連部分は次のとおりです。

回避策は、次のようにメニューのデータ コンテキストを親のデータ コンテキストに明示的にバインドすることです。

<ContextMenu DataContext="{Binding PlacementTarget.DataContext,
    RelativeSource={RelativeSource Self}}">

この魔法の呪文は、メニューのデータ コンテキストとその "配置ターゲット" (つまり、親) のデータ コンテキストの間に永続的なバインドを作成するように WPF に指示します。これは、親のデータ コンテキストが変更された後も機能し続けます。親の存続期間中に親のデータ コンテキストが変更されることが予想される場合にのみ、この呪文が必要です。

以前に見つけた別の解決策は、Opened イベントでコンテキスト メニューの DataContext をウィンドウの DataContext に手動で設定することでした。これには、コード ビハインド ファイルに追加の C# コードが必要であり、さまざまなシナリオに適応させる必要がある場合があります。したがって、上記の XAML のみの方法の方が優れていると思います。

于 2013-10-16T10:10:43.160 に答える