天天看點

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

場景:視訊上傳功能,上傳清單使用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}"