如何将变量作为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
Xmal位: