简体   繁体   English

使用Prism WPF在Datagrid中绑定命令

[英]Binding Command in Datagrid with Prism WPF

I have searched around google about my problem and cant find any answer that can solve my problem. 我搜索了谷歌关于我的问题,无法找到任何可以解决我的问题的答案。 I tried to binding a command from a button inside my datagrid in WPF. 我试图从WPF中的数据网格内的按钮绑定命令。 I used Prism to handle the MVVM. 我用Prism来处理MVVM。 Here is my code to bind the command: 这是我绑定命令的代码:

<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>

and here is my viewmodel which contains the Command function: 这是我的viewmodel,它包含Command函数:

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

When I tried to debug, it does not enter the ICommand. 当我尝试调试时,它不会进入ICommand。 So how can I bind my button inside the datagrid to my viewmodel? 那么如何将数据网格中的按钮绑定到我的viewmodel?

Your problem is because DataColumns are not part of the visual tree and therefore do not inherit the DataContext of the DataGrid. 您的问题是因为DataColumns不是可视化树的一部分,因此不会继承DataGrid的DataContext。

One way to potentially overcome this is to specify an ancestor with your binding: 可能解决此问题的一种方法是使用绑定指定祖先:

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

Another (slightly hacky) way is to declare a helper class that creates an attached property for the DataGridColumn class and then populates that property when the datacontext of the grid changes (it does this by handling the event changed at the FrameworkElement level and checking if the dependency object responsible for the event is a DataGrid): 另一种(略微hacky)方式是声明一个帮助器类,它为DataGridColumn类创建一个附加属性,然后在网格的datacontext发生更改时填充该属性(它通过处理在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);
        }
    }
}

You can find more details about this approach here . 您可以在此处找到有关此方法的更多详细信息

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM