一、問題場景:
使用WPF的DataGrid來展示表格資料,想要批量删除或者導出資料行時,由于SelectedItems屬性不支援MVVM的方式綁定(該屬性是隻讀屬性),是以可以通過指令參數的方式将該屬性值傳給指令,即利用CommandParameter将SelectedItems傳遞給删除或導出指令。
二、使用方式:
1.xaml部分
<DataGrid x:Name="dtgResult" ItemsSource="{Binding ResultInfo}" CanUserSortColumns="True" Height="205" Width="866" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="患者ID" Binding="{Binding PatientId}" MinWidth="46" IsReadOnly="True"/>
<DataGridTextColumn Header="姓名" Binding="{Binding PatientName}" MinWidth="46" IsReadOnly="True"/>
<DataGridTextColumn Header="性别" Binding="{Binding PatientGender}" MinWidth="46" IsReadOnly="True"/>
</DataGrid.Columns>
</DataGrid>
<Button x:Name="btnResultDel" Content="删除" Command="{Binding ResultDeleteCommand}" CommandParameter="{Binding SelectedItems,ElementName=dtgResult}"/>
2.C#部分
private RelayCommand _deleteCommand;
public ICommand ResultDeleteCommand
{
get
{
if (_deleteCommand == null)
{
_deleteCommand = new RelayCommand(param =>On_Delete_Command_Excuted(param));
}
return _deleteCommand;
}
}
private void On_Delete_Command_Excuted(Object param)
{
}
每次觸發ResultDeleteCommand,都會把控件dtgResult的SelectedItems屬性值作為參數param傳遞給On_Delete_Command_Excuted方法。
三、Tip
1.如何把Object類型的參數轉成List<T>呢? (其中T是DataGrid中每條資料的類型)
System.Collections.IList items = (System.Collections.IList)param;
var collection = items.Cast<T>();
var selectedItems = collection.ToList();
其中selectedItems就是使用者在DataGrid界面選中的多條資料行。
2.RelayCommand
/// <summary>
/// A command whose sole purpose is to relay its functionality to other objects by invoking delegates. The default return value for the CanExecute method is 'true'.
/// </summary>
public class RelayCommand : ICommand
{
readonly Action<object> _execute;
readonly Predicate<object> _canExecute;
/// <summary>
/// Creates a new command that can always execute.
/// </summary>
/// <param name="execute">The execution logic.</param>
public RelayCommand(Action<object> execute): this(execute, null)
{
}
/// <summary>
/// Creates a new command.
/// </summary>
/// <param name="execute">The execution logic.</param>
/// <param name="canExecute">The execution status logic.</param>
public RelayCommand(Action<object> execute, Predicate<object> canExecute)
{
if (execute == null)
throw new ArgumentNullException("execute");
_execute = execute;
_canExecute = canExecute;
}
public bool CanExecute(object parameter)
{
return _canExecute == null ? true : _canExecute(parameter);
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public void Execute(object parameter)
{
_execute(parameter);
}
}