1

以下のようなデータグリッド列があります。

<toolkit:DataGridTemplateColumn>
                        <toolkit:DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding Path=LabelName}" Background="{Binding Path=Color}">
                                    <TextBlock.ContextMenu>
                                        <ContextMenu>
                                            <MenuItem x:Name="Assign" Header="Assign"
                                                      mvvm:CommandBehavior.Event="Click"
                                                      mvvm:CommandBehavior.Command="{Binding Path=DataContext.EditLabelCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}, AncestorLevel='1'}}"
                                                      mvvm:CommandBehavior.CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}, Path=DataContext}"/>
                                        </ContextMenu>
                                    </TextBlock.ContextMenu>
                                </TextBlock>
                            </DataTemplate>
                        </toolkit:DataGridTemplateColumn.CellTemplate>

DataContext の EditLabelCommand にアクセスしようとしていますが、バインディング ソースが見つかりません。DataContext のコマンドにアクセスするにはどうすればよいですか?

4

1 に答える 1

3

DataContextは、a)DataContextを他の何かにバインドするか、b)コレクション内のアイテムごとに1回データテンプレートを繰り返すアイテムコントロール(またはこの場合はグリッド)のようなものを使用するときに、ビジュアルツリーを下に移動すると変化します。各アイテムのデータコンテキストを設定します。

この例では、メニュー項目にTextBlockと同じDataContextがあります。これは、データグリッドの各行にバインドされたオブジェクトになります。

コードに基づいて、UserControl全体のDataContextセットで使用可能なEditLabelCommandが1つあると思います。これは、グリッドにバインドしているコレクションの親である可能性があります。(これらの仮定のいずれかが間違っている場合は、私を訂正してください。)

この場合、実行できることがいくつかあります。

  • 相対バインディングを引き続き使用できます。これまで見てきたように、これは複雑でエラーが発生しやすく、データテンプレートやその他のXAMLを適切に再利用することにはなりません。このテクニックは避けることをお勧めします。

  • コマンドをデータコンテキスト全体に保持する簡単な方法は、WPFModel -View-ViewModelToolkitのCommandReferenceを使用することです。これにより、コマンドをリソースとして参照し、リソースバインディングを使用してコマンドにアクセスできます。このような:

    <UserControl.Resources>
        <mvvmToolkit:CommandReference x:Key = "EditLabelCommandReference" Command = "{Binding EditLabelCommand}" />
    </UserControl.Resources>

    <!-コマンドバインディングははるかに単純に見えます->
    mvvm:CommandBehavior.Command = "{StaticResource EditLabelCommandReference}"
  • 別の(おそらくより良い)手法は、各行にMVVMパターンを使用するようにリファクタリングすることです。このように、グリッドの行ごとに単純なViewModelを使用します。これにより、各行が独自の状態を維持できます。コマンド実装をこのViewModelに移動できるため、行ごとにコマンドがあり、引数を渡す必要はありません。これにより、一度に複数の行のラベルを編集できます。(これが要件の場合。)
于 2009-09-04T15:47:28.517 に答える