对于此列中的每个单元格,我想从我的视图模型中绑定一个命令,在每个可以执行该命令时,我不想发送我的项目源中每个项目的“实体”属性。
数据网格:
<DataGrid ItemsSource="{Binding Items}">
<DataGridTemplateColumn Header="C.. Header" >
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox IsChekced="{Binding Entity.IsIncluded, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
CommandParameter="{Binding Entity, Mode=OneWay}"
Command="{Binding DataContext.OnDicomAttributeIsIncluded, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Mode=OneWay}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid>
所以 Command 和 CommandParameter 为每个单元格中的每个 CheckBox 绑定,
问题是,当命令被绑定时,可以使用一个为 null 的参数来执行
调试时,似乎 CommandParameter 仅在 Command 之后绑定(因此为空值)
似乎在更新 CommandParameter 时复选框不会 Raise 可以执行(我使用反射器查看,我没有看到对 CommandParameter 属性的任何回调)。
我以前用其他类型的 ItemsControls 做过这种事情,这从来都不是问题,这似乎是由于处于 CellTemplate 的上下文中而引起的奇怪行为。
我在视图模型中的命令:
private RelayCommand<DicomAttributeInfo> _onDicomAttributeIncluded;
public RelayCommand<DicomAttributeInfo> OnDicomAttributeIsIncluded
{
get
{
if (_onDicomAttributeIncluded == null)
_onDicomAttributeIncluded = new RelayCommand<DicomAttributeInfo>(DicomAttributeIncluded);
return _onDicomAttributeIncluded;
}
}
我的 ICommand 实现:
public class RelayCommand<T> : ICommand
{
private Predicate<T> _canExecute;
private Action<T> _execute;
public RelayCommand(Action<T> execute, Predicate<T> canExecute = null)
{
_execute = execute;
_canExecute = canExecute;
}
private void Execute(T parameter)
{
_execute(parameter);
}
private bool CanExecute(T parameter)
{
return _canExecute == null ? true : _canExecute(parameter);
}
public bool CanExecute(object parameter)
{ // Here is the problem parameter is null after command is bound
return parameter == null ? false : CanExecute((T)parameter);
}
public void Execute(object parameter)
{
_execute((T)parameter);
}
public event EventHandler CanExecuteChanged;
public void RaiseCanExecuteChanged()
{
var temp = Volatile.Read(ref CanExecuteChanged);
if (temp != null)
temp(this, new EventArgs());
}
}
有任何想法吗?
编辑 :
我可以找到一些方法:
_onDicomAttributeIncluded.RaiseCanExecuteChanged();
我相信这会解决问题,因为命令将再次查询它的所有命令参数,并且命令参数将对其所有绑定进行采样,它似乎不合理,它不是由引擎盖下的复选框控件处理的(正如我提到的在 CommandParameter 更改之前)