绑定到数据网格中的命令

时间:2009-02-24 13:27:11

标签: .net wpf data-binding mvvm

我在WPF应用程序中使用M-V-VM模式。我将ViewModel绑定到ContentControl并使用窗口资源中定义的数据模板来呈现该ViewModel的视图(UserControl)。

在ViewModel中,我有一组项目。我将该集合绑定到WPF工具包中提供的数据网格。同样在视图模型中,我定义了一个RemoveItem命令,该命令接受要删除的项ID的参数。

如何在数据网格中绑定该命令?网格的数据上下文就是那个集合,所以类似于:

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

不起作用 - 它无法找到命令。我想我需要做RelativeSource绑定,但那会是什么样子? Ancestor类型是UserControl还是ContentControl?我的ViewModel作为DataContext驻留在哪里?

还是我离开这里?

2 个答案:

答案 0 :(得分:37)

是的,你只需要升级一级。我首先尝试与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>

您只需要搜索,直到数据上下文成为您的视图模型。如果您愿意,可以搜索UserControl - 不确定它真的很重要。两者都是相当脆弱的绑定,这就是我更喜欢ElementName方法的原因。

答案 1 :(得分:1)

我喜欢在名称为ViewModel的控件的datacontext中定义viewmodel。使用ElementName

更容易编写绑定
...
<UserControl.DataContext>
    <local:UserControlViewModel x:Name="ViewModel"/>
</UserControl.DataContext>
...

...
<DataGridTemplateColumn  Width="30">
    <DataGridTemplateColumn.CellTemplate>
         <DataTemplate>
             <Button Command="{Binding RemoveCommand, ElementName=ViewModel}" 
                     CommandParameter="{Binding}">Remove</Button>
         </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
...

请注意,在这种情况下,Command Parameter是行的整个数据对象。有时比

更好
CommandParameter="{Binding Id}"  

因为您不必再​​次查找数据。