18

WPF アプリで MV-VM パターンを使用しています。ViewModel を ContentControl にバインドし、ウィンドウ リソースで定義されたデータ テンプレートを使用して、その ViewModel のビュー (UserControl) をレンダリングしています。

ViewModel には、アイテムのコレクションがあります。そのコレクションを、WPF ツールキットで提供されるデータ グリッドにバインドしています。また、ビュー モデルには、削除する項目 ID の引数を取る RemoveItem コマンドが定義されています。

データ グリッドでそのコマンドにどのようにバインドしますか? グリッドのデータ コンテキストはそのコレクションなので、次のようになります。

<Button Command="{Binding Path=RemoveCommand}" CommandParameter="{Binding Path=id}">X</Button>

動作しません - コマンドが見つかりません。RelativeSource バインディングを行う必要があると思いますが、それはどのようなものでしょうか? 祖先の型は UserControl でしょうか、それとも ContentControl でしょうか? ViewModel は DataContext としてどこにありますか?

それとも私はここから離れていますか?

4

2 に答える 2

39

ええ、レベルを上げればいいだけです。ElementName最初にバインディングを試し、RelativeSource必要な場合にのみ頼ります。たとえば、私はこれを好みます:

<DataGrid x:Name="_grid">
    ...
        <Button Command="{Binding DataContext.RemoveItem, ElementName=_grid}"/>
    ...
</DataGrid>

とはいえ、XAML コンパイラは、要素名とコントロールのスコープに関しては複雑な問題を抱えている可能性があるため、次のように頼る必要がある場合がありますRelativeSource

<DataGrid x:Name="_grid">
    ...
  <Button Command="{Binding DataContext.RemoveItem, 
                    RelativeSource={RelativeSource FindAncestor, 
                                    AncestorType={x:Type DataGrid}}
                   }"/>
    ...
</DataGrid>

データ コンテキストがビュー モデルになるまで検索するだけです。必要に応じて a を検索できますが、UserControlそれが本当に重要かどうかはわかりません。どちらも非常に壊れやすいバインディングであるため、私はこのElementNameアプローチを好みます。

于 2009-02-24T13:44:29.590 に答える