DataGrid绑定命令以行选择

18

当用户在DataGrid中选择一行时,我希望执行一个命令。

我知道可以将单元格内容包装在按钮中(虽然我不想使用按钮样式)-但我不想在单元格级别上操作。

我也知道可以使用behaviors将命令链接到事件。 但最好不要为这样的常见任务而采用behaviors。

是否可以通过纯旧式命令数据绑定来实现这一点?

因此:1)用户单击DataGrid行2)视图模型上的命令被触发。

2个回答

50

您应该使用“Interactivity”程序集和SelectionChanged事件。

<DataGrid AutoGenerateColumns="False" ItemsSource="{Binding People}">
    <DataGrid.Columns>
        <DataGridTextColumn Header="ID" Binding="{Binding ID}" />
        <DataGridTextColumn Header="Name" Binding="{Binding Name}" />
    </DataGrid.Columns>
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="SelectionChanged">
            <i:InvokeCommandAction Command="{Binding MyCommand}" />
        </i:EventTrigger>
    </i:Interaction.Triggers>
</DataGrid>

其中"i"是命名空间:

xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"

你也可以写一个绑定到DataGrid的SelectedItem属性的绑定器,在设置访问器中调用你的命令,但我上面介绍的第一种解决方案更好。

如果你想从主视图模型中调用命令并传递DataGrid的SelectedItem,你可以使用CommandParameter:

<i:Interaction.Triggers>
    <i:EventTrigger EventName="SelectionChanged">
        <i:InvokeCommandAction Command="{Binding MyCommand}" 
        CommandParameter="{Binding Path=SelectedItem, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid}}" />
    </i:EventTrigger>
</i:Interaction.Triggers>

当items有自己的命令时,您可以使用以下代码:

<i:Interaction.Triggers>
    <i:EventTrigger EventName="SelectionChanged">
        <i:InvokeCommandAction Command="{Binding Path=SelectedItem.MyCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid}}" />
    </i:EventTrigger>
</i:Interaction.Triggers>

如果元素有自己的视图模型,并将其分配给DataContext,则可以使用以下代码:

 <i:Interaction.Triggers>
    <i:EventTrigger EventName="SelectionChanged">
        <i:InvokeCommandAction Command="{Binding Path=SelectedItem.DataContext.MyCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid}}" />
    </i:EventTrigger>
</i:Interaction.Triggers>

因为看起来不错且相对简单,所以我将其标记为目前的答案。谢谢!我也尝试过SelectedItem,但由于虚拟化存在一些问题。总的来说,DataGrid似乎有一些bug。 - Bent Rasmussen
1
@BentRasmussen 再次检查我的答案,我添加了更多的例子。 - kmatyaszek
@kmatyaszek,执行命令相比将SelectedItem绑定到ViewModel属性SelectedObject上的优点是什么? - Stefan Vasiljevic
那个命名空间引用似乎对我不起作用。"找不到类型Interaction",和/或者"名称“Interaction”在命名空间中不存在"。 - Jonathan Tuzman
1
@JonathanTuzman 请查看这个问题:https://dev59.com/Ymsy5IYBdhLWcg3wtwa9 - kmatyaszek
显示剩余2条评论

2
请注意,@kmatyaszek的回答在.NET 5.0及以上版本中已经过时,我们应该使用Microsoft.Xaml.Behaviors代替Microsoft.Expression.Interactions

因此,命名空间中的i应该是:

xmlns:i="http://schemas.microsoft.com/xaml/behaviors"

详情请参见此处


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接