18

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

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

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

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

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

于 2009-02-24T13:44:29.590 回答
2

我喜欢在名为 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>
...

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

CommandParameter="{Binding Id}"  

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

于 2017-05-09T08:41:13.487 回答