4

私は自分の問題についてグーグルで検索しましたが、問題を解決できる答えが見つかりません。WPF のデータグリッド内のボタンからコマンドをバインドしようとしました。Prism を使用して MVVM を処理しました。コマンドをバインドするコードは次のとおりです。

<DataGrid AutoGenerateColumns="False" 
              ...
              SelectedItem="{Binding OrderDetail}"
              ItemsSource="{Binding ListOrderDetail}">
        <DataGrid.Columns>
            <DataGridTemplateColumn>
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <Button Content="Deliver Order" 
                                Command="{Binding Path=DataContext.DeliverOrderCommand}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Columns>
    </DataGrid>

Command関数を含むビューモデルは次のとおりです。

public ICommand DeliverOrderCommand
    {
        get 
        {
            if (deliverOrderCommand == null)
                deliverOrderCommand = new DelegateCommand(DeliverOrderFunc);
            return deliverOrderCommand; 
        }
        set { deliverOrderCommand = value; }
    }

デバッグしようとしたらICommandに入らない。では、データグリッド内のボタンをビューモデルにバインドするにはどうすればよいでしょうか?

4

1 に答える 1

5

問題は、DataColumns がビジュアル ツリーの一部ではないため、DataGrid の DataContext を継承しないためです。

これを潜在的に克服する 1 つの方法は、バインディングで祖先を指定することです。

<DataGridTemplateColumn.CellTemplate>
    <DataTemplate>
        <Button Content="Deliver Order" 
                Command="{Binding  Path=DataContext.DeliverPesananCommand
                                  ,RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" 
                />
    </DataTemplate>
</DataGridTemplateColumn.CellTemplate>

もう 1 つの (ややハックな) 方法は、DataGridColumn クラスの添付プロパティを作成するヘルパー クラスを宣言し、グリッドのデータ コンテキストが変更されたときにそのプロパティを設定することです (これは、FrameworkElement レベルで変更されたイベントを処理し、イベントを担当する依存オブジェクトは DataGrid です):

public class DataGridContextHelper
{

    static DataGridContextHelper()
    {
        DependencyProperty dp = FrameworkElement.DataContextProperty.AddOwner(typeof(DataGridColumn));
        FrameworkElement.DataContextProperty.OverrideMetadata( typeof(DataGrid)
                                                              ,new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.Inherits, OnDataContextChanged)
                                                             );
    }

    public static void OnDataContextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var grid = d as DataGrid;
        if (grid == null) return;

        foreach (var col in grid.Columns)
        {
            col.SetValue(FrameworkElement.DataContextProperty, e.NewValue);
        }
    }
}

このアプローチの詳細については、こちらを参照してください

于 2012-11-12T06:58:55.953 に答える