WPF中DataGrid控件内Button的Command和CommandParameter的绑定

场景:视频上传功能,上传列表使用DataGrid控件,视频有不同的状态对应不同的操作,DataGrid中最后一列为操作列,里面是Button控件。希望点击Button后执行对应的操作,但是设置Button的 Command="{Binding VideoOperationCommand}"后触发不了操作。

XAML代码如下:

[html] view plain copy
 
  1. <DataGrid ItemsSource="{Binding VideoList}">  
  2.     <DataGrid.Columns>  
  3.         <!--序号-->  
  4.         <DataGridTextColumn Header="序号" Width="80" Binding="{Binding Index}"/>  
  5.         <!--视频名称-->  
  6.         <DataGridTextColumn Header="视频名称" Width="300" Binding="{Binding Name}" />   
  7.         <!--文件大小-->  
  8.         <DataGridTextColumn Header="文件大小" Width="120" Binding="{Binding SizeString}" />  
  9.         <!--源视频地址-->  
  10.         <DataGridTextColumn Header="源视频地址" Width="280" Binding="{Binding SourcePath}" />  
  11.         <!--状态-->  
  12.         <DataGridTextColumn Header="状态" Width="120" Binding="{Binding StatusString}" />  
  13.         <!--上传进度-->  
  14.         <DataGridTemplateColumn Header="上传进度" Width="260">  
  15.             <DataGridTemplateColumn.CellTemplate>  
  16.                 <DataTemplate>  
  17.                     <ProgressBar Value="{Binding Progress}" Margin="20,0"/>  
  18.                 </DataTemplate>  
  19.             </DataGridTemplateColumn.CellTemplate>  
  20.         </DataGridTemplateColumn>  
  21.         <!--上传速度-->  
  22.         <DataGridTextColumn Header="上传速度" Width="150" Binding="{Binding SpeedString}" />  
  23.         <!--操作-->  
  24.         <DataGridTemplateColumn Header="操作" MinWidth="120">  
  25.             <DataGridTemplateColumn.CellTemplate>  
  26.                 <DataTemplate>  
  27.                     <Button Content="{Binding OperationString}"  
  28.                             Command="{Binding VideoOperationCommand}"  
  29.                             CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid}, Path=SelectedItem}" />  
  30.                 </DataTemplate>  
  31.             </DataGridTemplateColumn.CellTemplate>  
  32.         </DataGridTemplateColumn>  
  33.     </DataGrid.Columns>  
  34. </DataGrid>  

分析:因为DataGrid的ItemsSource绑定了VideoList,VideoList是一个Video类的列表,DataGrid里面控件的DataContext就成了Video也就是里面控件的Binding都是Video的属性,比如视频名称(Binding="{Binding Name}")。而Video里没有VideoOperationCommand,所以就不能触发操作了。

解决:知道了原因就好说了,把Button的Command绑定为ViewModel里面的VideoOperationCommand就好了,而DataGrid的DataContext就是ViewModel,那这样做就好了:

[html] view plain copy
 
  1. <!--操作-->  
  2. <DataGridTemplateColumn Header="操作" MinWidth="120">  
  3.     <DataGridTemplateColumn.CellTemplate>  
  4.         <DataTemplate>  
  5.             <Button Content="{Binding OperationString}"  
  6.                             Command="{Binding DataContext.VideoOperationCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid}}"  
  7.                             CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid}, Path=SelectedItem}" />  
  8.         </DataTemplate>  
  9.     </DataGridTemplateColumn.CellTemplate>  
  10. </DataGridTemplateColumn>  

通过上面的分析,我们知道,可以直接为命令传递当前Video的某一个属性,比如视频名称:

[html] view plain copy
 
    1. CommandParameter="{Binding Name}"  
原文地址:https://www.cnblogs.com/sjqq/p/8454530.html