C# 如何将变量作为CommandParameter传递
我试图将变量作为参数从ViewModel发送到命令。该命令如下所示:C# 如何将变量作为CommandParameter传递,c#,wpf,mvvm,command,commandparameter,C#,Wpf,Mvvm,Command,Commandparameter,我试图将变量作为参数从ViewModel发送到命令。该命令如下所示: public class EditPersonCommand : ICommand { private bool _CanExecute = false; public bool CanExecute(object parameter) { PersonModel p = parameter as PersonModel; CanExecuteProperty = (p != null) &a
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);
}
}
}
}
}
public class PersonViewModel : ViewModelBase
{
private PersonModel _PersonModel;
private EditPersonCommand _EditPersonCommand;
///<remarks>
/// must use the parameterless constructor to satisfy <Window.Resources>
///</remarks>
public PersonViewModel()
: this(new PersonModel())
{
}
public PersonViewModel(PersonModel personModel)
{
_PersonModel = personModel;
}
public ICommand EditPersonCommand
{
get
{
if (_EditPersonCommand == null)
{
_EditPersonCommand = new EditPersonCommand();
}
return _EditPersonCommand;
}
}
}
<Button Content="Edit" HorizontalAlignment="Right" Height="20" Width="80"
Command="{Binding EditPersonCommand}"
CommandParameter="{Binding _PersonModel}" />
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);
}
}
}
}
}
public class PersonViewModel : ViewModelBase
{
private PersonModel _PersonModel;
private EditPersonCommand _EditPersonCommand;
///<remarks>
/// must use the parameterless constructor to satisfy <Window.Resources>
///</remarks>
public PersonViewModel()
: this(new PersonModel())
{
}
public PersonViewModel(PersonModel personModel)
{
_PersonModel = personModel;
}
public ICommand EditPersonCommand
{
get
{
if (_EditPersonCommand == null)
{
_EditPersonCommand = new EditPersonCommand();
}
return _EditPersonCommand;
}
}
}
<Button Content="Edit" HorizontalAlignment="Right" Height="20" Width="80"
Command="{Binding EditPersonCommand}"
CommandParameter="{Binding _PersonModel}" />
并将xaml更改为:
<Button Content="Edit" HorizontalAlignment="Right" Height="20" Width="80"
Command="{Binding EditPersonCommand}"
CommandParameter="{Binding PersonModelProp}" />
但还是没有运气。ViewModel确实实现了INotifyPropertyChanged
\u PersonModel
是私有的,因此无法访问。创建公开它的公共属性,并绑定到CommandParameter
中的公共属性。请记住将属性设置为依赖属性(技术上不是必需的,但有帮助),并且ViewModel应实现INotifyProperty changed并触发PropertyChanged事件,以便更新绑定。CommandParameter是否始终为null,或者您是否仅在第一次执行时检查它
在这种情况下,声明属性的顺序似乎很重要,因为设置Command属性会导致CanExecute在设置CommandParameter之前立即启动
尝试在命令属性之前移动CommandParameter属性:
<Button Content="Edit" HorizontalAlignment="Right" Height="20" Width="80"
CommandParameter="{Binding PersonModelProp}"
Command="{Binding EditPersonCommand}" />
以及视图模型:
public class PersonViewModel : ViewModelBase
{
private PersonModel _PersonModel;
private EditPersonCommand _EditPersonCommand;
///<remarks>
/// must use the parameterless constructor to satisfy <Window.Resources>
///</remarks>
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();
}
}
}
公共类PersonViewModel:ViewModelBase
{
私人个人模型(PersonModel);;
私人编辑命令(EditPersonCommand);;
///
///必须使用无参数构造函数才能满足
///
公共PersonViewModel()
:此(新PersonModel())
{
_EditPersonCommand=新的EditPersonCommand();
}
公共PersonViewModel(PersonModel PersonModel)
{
_PersonModel=PersonModel;
}
公共ICommand编辑器命令
{
得到
{
返回_EditPersonCommand;
}
}
公共人物模型人物模型
{
得到
{
return\u PersonModel;
}
设置
{
_PersonModel=值;
OnPropertyChanged(“PersonModelProp”);
EditPersonCommand.RaiseCanExecuteChanged();
}
}
}
答案有两点: 首先,正如@akton所提到的,您只能绑定到公共属性。不过,它不必是一个依赖属性 其次,我花了很多时间才弄明白,您必须在Command属性之前设置CommandParameter的绑定。i、 e
<Button Content="Edit" HorizontalAlignment="Right" Height="20" Width="80"
CommandParameter="{Binding PersonModelProp}"
Command="{Binding EditPersonCommand}" />
希望这有帮助:)我认为您的EditPersonCommand中有问题(它没有被触发)。我与relayCommand进行了检查,结果正常 代码如下: 视图模型:
public class PersonViewModel : ViewModelBase
{
private PersonModel _PersonModel;
private ICommand _EditPersonCommand;
///<remarks>
/// must use the parameterless constructor to satisfy <Window.Resources>
///</remarks>
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");
}
}
}
公共类PersonViewModel:ViewModelBase
{
私人个人模型(PersonModel);;
私人ICommand_EditPersonCommand;
///
///必须使用无参数构造函数才能满足
///
公共PersonViewModel()
:此(新PersonModel())
{
}
公共PersonViewModel(PersonModel PersonModel)
{
PersonModelProp=personModel;
}
公共ICommand编辑器命令
{
得到
{
if(_EditPersonCommand==null)
{
_EditPersonCommand=新的RelayCommand(ExecuteEditPerson、CanExecuteEditPerson);
}
返回_EditPersonCommand;
}
}
私有布尔CanExecuteEditPerson(对象参数)
{
PersonModel p=作为PersonModel的参数;
返回值(p!=null)&(p.Age>0);
}
私有void ExecuteEditPerson(对象o)
{
}
公共人物模型人物模型
{
得到
{
return\u PersonModel;
}
设置
{
_PersonModel=值;
NotifyPropertyChanged(“PersonModelProp”);
}
}
}
还有这个RelayCommand(火灾事件正常!)
公共类RelayCommand:ICommand
{
#区域常数和字段
私有只读谓词canExecute;
私有只读操作执行;
#端区
#区域构造函数和析构函数
公共中继命令(操作执行)
:此(执行,空)
{
}
公共RelayCommand(操作执行,谓词canExecute)
{
if(execute==null)
{
抛出新的ArgumentNullException(“执行”);
}
this.execute=execute;
this.canExecute=canExecute;
}
#端区
#地区活动
公共事件事件处理程序CanExecuteChanged
{
添加
{
CommandManager.RequerySuggested+=值;
}
去除
{
CommandManager.RequerySuggested-=值;
}
}
#端区
#区域实现的接口
#区域ICommand
[调试步骤至]
公共布尔CanExecute(对象参数)
{
返回this.canExecute==null | | this.canExecute(参数);
}
public void Execute(对象参数)
{
执行(参数);
}
#端区
#端区
}
Xmal:
我总是将绑定属性公开
,我想他们一定对此不确定。这不是问题的原因,但从CanExecute
提出CanExecute更改
是错误的<当调用者再次调用CanExecute
时,应引发code>CanExecuteChanged。根据您当前的CanExecute
实施情况,当一个人的年龄发生变化时,您应该提高CanExecuteChanged
,但您可能也不会提高该事件。您尝试过吗?什么错误
<Button Content="Edit" HorizontalAlignment="Right" Height="20" Width="80"
CommandParameter="{Binding PersonModelProp}"
Command="{Binding EditPersonCommand}" />