如何将变量作为CommandParameter传递

我正在尝试将ViewModel中的变量作为参数发送到命令。 该命令如下所示:

public class EditPersonCommand : ICommand { private bool _CanExecute = false; public bool CanExecute(object parameter) { PersonModel p = parameter as PersonModel; CanExecuteProperty = (p != null) && (p.Age > 0); return CanExecuteProperty; } public event EventHandler CanExecuteChanged; public void Execute(object parameter) { } private bool CanExecuteProperty { get { return _CanExecute; } set { if (_CanExecute != value) { _CanExecute = value; EventHandler can_execute = CanExecuteChanged; if (can_execute != null) { can_execute.Invoke(this, EventArgs.Empty); } } } } } 

ViewModel看起来像这样:

 public class PersonViewModel : ViewModelBase { private PersonModel _PersonModel; private EditPersonCommand _EditPersonCommand; /// /// must use the parameterless constructor to satisfy  /// public PersonViewModel() : this(new PersonModel()) { } public PersonViewModel(PersonModel personModel) { _PersonModel = personModel; } public ICommand EditPersonCommand { get { if (_EditPersonCommand == null) { _EditPersonCommand = new EditPersonCommand(); } return _EditPersonCommand; } } } 

xaml看起来像这样:

 

我已经尝试在ViewModel中创建一个属性而不是使用私有本地变量名,但这也没有用。 object parameter在对CanExecute的调用中始终显示为null ,并且永远不会启用该按钮。 如果我将CommandParameter值更改为Hello ,那么我在调用CanExecute收到Hello ,所以我不确定为什么变量不起作用。 任何帮助,将不胜感激。

更新:我也试过为模型创建一个公共属性(我真的不想公开模型,但只是尝试了它是否有效,但它没有)。

 // Added this to the ViewModel public PersonModel PersonModelProp { get { return _PersonModel; } set { _PersonModel = value; OnPropertyChanged("PersonModelProp"); } } 

并将xaml更改为:

 

但仍然没有运气。 ViewModel确实实现了INotifyPropertyChanged

CommandParameter是否始终为null或者您是仅在第一次执行时进行检查?

在这种情况下,您声明属性的顺序似乎很重要,因为设置Command属性会导致CanExecute在设置CommandParame之前立即触发。

尝试在Command属性之前移动CommandParameter属性:

  

另外,请看这里和这里 。

编辑

为确保正确引发事件,应在PersonModelProp值更改时引发CanExecuteChanged事件。

命令:

 public class EditPersonCommand : ICommand { public bool CanExecute(object parameter) { PersonModel p = parameter as PersonModel; return p != null && p.Age > 0; } public event EventHandler CanExecuteChanged; public void Execute(object parameter) { //command implementation } public void RaiseCanExecuteChanged() { var handler = CanExecuteChanged; if(handler != null) { handler(this, EventArgs.Empty); } } } 

和视图模型:

 public class PersonViewModel : ViewModelBase { private PersonModel _PersonModel; private EditPersonCommand _EditPersonCommand; /// /// must use the parameterless constructor to satisfy  /// public PersonViewModel() : this(new PersonModel()) { _EditPersonCommand = new EditPersonCommand(); } public PersonViewModel(PersonModel personModel) { _PersonModel = personModel; } public ICommand EditPersonCommand { get { return _EditPersonCommand; } } public PersonModel PersonModelProp { get { return _PersonModel; } set { _PersonModel = value; OnPropertyChanged("PersonModelProp"); EditPersonCommand.RaiseCanExecuteChanged(); } } } 

两点答案:

首先,正如@akton所提到的,您只能绑定到公共属性 。 但它不一定DependencyProperty

其次,我需要弄清楚的是,你必须在Command属性之前设置CommandParameter的绑定。 即

  

希望这可以帮助 :)

_PersonModel是私有的,因此无法访问。 创建一个公开属性并将其绑定到CommandParameter的公共属性。 记住要使属性成为依赖属性(技术上不是必需的,但它有帮助),ViewModel应该实现更改的INotifyProperty并触发PropertyChanged事件,以便更新绑定。

我认为你的EditPersonCommand有问题(它没有被解雇)。我用relayCommand检查它,它工作!

这是代码:

视图模型:

  public class PersonViewModel : ViewModelBase { private PersonModel _PersonModel; private ICommand _EditPersonCommand; /// /// must use the parameterless constructor to satisfy  /// public PersonViewModel() : this(new PersonModel()) { } public PersonViewModel(PersonModel personModel) { PersonModelProp = personModel; } public ICommand EditPersonCommand { get { if (_EditPersonCommand == null) { _EditPersonCommand = new RelayCommand(ExecuteEditPerson,CanExecuteEditPerson); } return _EditPersonCommand; } } private bool CanExecuteEditPerson(object parameter) { PersonModel p = parameter as PersonModel; return (p != null) && (p.Age > 0); } private void ExecuteEditPerson(object o) { } public PersonModel PersonModelProp { get { return _PersonModel; } set { _PersonModel = value; NotifyPropertyChanged("PersonModelProp"); } } } 

而这个RelayCommand(火灾事件还可以!)

  public class RelayCommand : ICommand { #region Constants and Fields private readonly Predicate canExecute; private readonly Action execute; #endregion #region Constructors and Destructors public RelayCommand(Action execute) : this(execute, null) { } public RelayCommand(Action execute, Predicate canExecute) { if (execute == null) { throw new ArgumentNullException("execute"); } this.execute = execute; this.canExecute = canExecute; } #endregion #region Events public event EventHandler CanExecuteChanged { add { CommandManager.RequerySuggested += value; } remove { CommandManager.RequerySuggested -= value; } } #endregion #region Implemented Interfaces #region ICommand [DebuggerStepThrough] public bool CanExecute(object parameter) { return this.canExecute == null || this.canExecute(parameter); } public void Execute(object parameter) { this.execute(parameter); } #endregion #endregion } 

Xmal位: