場景:視頻上傳功能,上傳列表使用DataGrid控件,視頻有不同的狀態對應不同的操作,DataGrid中最后一列為操作列,里面是Button控件。希望點擊Button后執行對應的操作,但是設置Button的 Command="{Binding VideoOperationCommand}"后觸發不了操作。
XAML代碼如下:
- <DataGrid ItemsSource="{Binding VideoList}">
- <DataGrid.Columns>
- <!--序號-->
- <DataGridTextColumn Header="序號" Width="80" Binding="{Binding Index}"/>
- <!--視頻名稱-->
- <DataGridTextColumn Header="視頻名稱" Width="300" Binding="{Binding Name}" />
- <!--文件大小-->
- <DataGridTextColumn Header="文件大小" Width="120" Binding="{Binding SizeString}" />
- <!--源視頻地址-->
- <DataGridTextColumn Header="源視頻地址" Width="280" Binding="{Binding SourcePath}" />
- <!--狀態-->
- <DataGridTextColumn Header="狀態" Width="120" Binding="{Binding StatusString}" />
- <!--上傳進度-->
- <DataGridTemplateColumn Header="上傳進度" Width="260">
- <DataGridTemplateColumn.CellTemplate>
- <DataTemplate>
- <ProgressBar Value="{Binding Progress}" Margin="20,0"/>
- </DataTemplate>
- </DataGridTemplateColumn.CellTemplate>
- </DataGridTemplateColumn>
- <!--上傳速度-->
- <DataGridTextColumn Header="上傳速度" Width="150" Binding="{Binding SpeedString}" />
- <!--操作-->
- <DataGridTemplateColumn Header="操作" MinWidth="120">
- <DataGridTemplateColumn.CellTemplate>
- <DataTemplate>
- <Button Content="{Binding OperationString}"
- Command="{Binding VideoOperationCommand}"
- CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid}, Path=SelectedItem}" />
- </DataTemplate>
- </DataGridTemplateColumn.CellTemplate>
- </DataGridTemplateColumn>
- </DataGrid.Columns>
- </DataGrid>
分析:因為DataGrid的ItemsSource綁定了VideoList,VideoList是一個Video類的列表,DataGrid里面控件的DataContext就成了Video也就是里面控件的Binding都是Video的屬性,比如視頻名稱(Binding="{Binding Name}")。而Video里沒有VideoOperationCommand,所以就不能觸發操作了。
解決:知道了原因就好說了,把Button的Command綁定為ViewModel里面的VideoOperationCommand就好了,而DataGrid的DataContext就是ViewModel,那這樣做就好了:
- <!--操作-->
- <DataGridTemplateColumn Header="操作" MinWidth="120">
- <DataGridTemplateColumn.CellTemplate>
- <DataTemplate>
- <Button Content="{Binding OperationString}"
- Command="{Binding DataContext.VideoOperationCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid}}"
- CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid}, Path=SelectedItem}" />
- </DataTemplate>
- </DataGridTemplateColumn.CellTemplate>
- </DataGridTemplateColumn>
通過上面的分析,我們知道,可以直接為命令傳遞當前Video的某一個屬性,比如視頻名稱:
- CommandParameter="{Binding Name}"