[英]copy textbox value to another when click on Button Command in WPF MVVM
[英]WPF MVVM button command that gets textbox value
我在了解按钮命令的工作方式时遇到了很大的麻烦。 我有这样的东西
{Binding TxtBox}
从模型中获取价值,假设它是“ aaa”。 我想单击按钮,值应该出现在第二个文本框中(带有{Binding TxtBox2}
文本框中)。
这是我的xaml:
<TextBox Text="{Binding TxtBox, Source={StaticResource viewModel}}" />
<TextBox Text="{Binding TxtBox2, Source={StaticResource viewModel}}" />
<Button Command="{Binding ClickCommand}"/>
这是我的ViewModel:
public class CommandHandler : ICommand
{
private Action _action;
private bool _canExecute;
public CommandHandler(Action action, bool canExecute)
{
_action = action;
_canExecute = canExecute;
}
public bool CanExecute(object parameter)
{
return _canExecute;
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
_action();
}
}
我真的需要这个CommandHandler
类吗? 我从网上复制了代码。
public string TxtBox
{
get { return Model.TxtBoxValue; }
set { Model.TxtBoxValue = value; }
}
public string TxtBox2 { get; set; }
private ICommand _clickCommand;
public ICommand ClickCommand
{
get
{
return _clickCommand ?? (_clickCommand = new CommandHandler(() => MyAction(), _canExecute)); // I believe that when the button is clicked MyAction() is triggered, right?
}
}
private bool _canExecute = true;
public void MyAction()
{
this.TxtBox2 = this.TxtBox; // should something like this work? Because right now it doesn't
}
第二个文本框的绑定永远不会收到有关其绑定属性已更改的通知。 设置this.TxtBox2时,应触发该属性的propertychanged事件,以便更新绑定。 有关绑定的所有信息,请参见思考链接
我不知道您是否使用棱镜作为mvvm框架,但这是DelegateCommand类附带的。 我认为.net框架中没有简单/轻量级的实现。 有关mvvm框架和委托命令,请参见此链接。
视图通过PropertyChanged事件对绑定更改作出反应,而您没有事件。 绑定到View实现INotifyPropertyChanged的任何东西,然后在props更改时触发事件,并且都准备好绑定起作用(一种或两种方式)。
更改模型使其看起来像这样,它应该对您有用。
public class MyViewModel : INotifyPropertyChanged
{
#region INotifyPropertyChanged Members
[field: NonSerialized]
public event PropertyChangedEventHandler PropertyChanged = null;
protected virtual void RaisePropertyChanged(string propName)
{
if(PropertyChanged != null)
{
Task.Run(() => PropertyChanged(this, new PropertyChangedEventArgs(propName)));
}
}
#endregion
public string TxtBox
{
get { return Model.TxtBoxValue; }
set
{
Model.TxtBoxValue = value;
RaisePropertyChanged("TxtBox");
}
}
// presuming TxtBox2Value is in Model...else use a field
public string TxtBox2
{
get { return Model.TxtBox2Value; }
set
{
Model.TxtBox2Value = value;
RaisePropertyChanged("TxtBox2");
}
}
private ICommand _clickCommand;
public ICommand ClickCommand
{
get
{
return _clickCommand ?? (_clickCommand = new CommandHandler(() => MyAction(), _canExecute)); // I believe that when the button is clicked MyAction() is triggered, right?
}
}
private bool _canExecute = true;
public void MyAction()
{
this.TxtBox2 = this.TxtBox; // should something like this work? Because right now it doesn't
}
}
IMO-最好让模型实现INotifyPropertyChanged,然后直接绑定到它,而不是将其包装在ViewModel中。 如果Model:INotifyPropertyChanged,则您的ViewModel现在看起来像这样:
public class MyViewModel
{
// fire prop changed event here if this model will be swapped out after the ctor...otherwise don't worry about it
public Model Model { get; set; }
private ICommand _clickCommand;
public ICommand ClickCommand
{
get
{
return _clickCommand ?? (_clickCommand = new CommandHandler(() => MyAction(), _canExecute));
}
}
private bool _canExecute = true;
public void MyAction()
{
Model = new Model();
Model.TxtBox2 = "Some new value";
}
}
...而您的xaml更改为:
<TextBox Text="{Binding Model.TxtBox, Source={StaticResource viewModel}}" />
<TextBox Text="{Binding Model.TxtBox2, Source={StaticResource viewModel}}" />
<Button Command="{Binding ClickCommand}"/>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.