Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/290.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 获取文本框值的WPF MVVM按钮命令_C#_Wpf_Xaml_Mvvm - Fatal编程技术网

C# 获取文本框值的WPF MVVM按钮命令

C# 获取文本框值的WPF MVVM按钮命令,c#,wpf,xaml,mvvm,C#,Wpf,Xaml,Mvvm,我很难理解按钮命令是如何工作的。我有类似的东西 {Binding TxtBox}从模型中获取值,假设它是“aaa”。我想单击按钮,值应该出现在第二个文本框中(带有{Binding TxtBox2}) 这是我的xaml: <TextBox Text="{Binding TxtBox, Source={StaticResource viewModel}}" /> <TextBox Text="{Binding TxtBox2, Source={StaticResource view

我很难理解按钮命令是如何工作的。我有类似的东西

{Binding TxtBox}
从模型中获取值,假设它是“aaa”。我想单击按钮,值应该出现在第二个文本框中(带有
{Binding TxtBox2}

这是我的xaml:

<TextBox Text="{Binding TxtBox, Source={StaticResource viewModel}}" />
<TextBox Text="{Binding TxtBox2, Source={StaticResource viewModel}}" />
<Button Command="{Binding ClickCommand}"/>
我真的需要这个
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事件,以便更新绑定。


我不知道您是否使用prism作为mvvm框架,但这是DelegateCommand类附带的。我认为在.net框架中没有简单/轻量级的实现

视图通过PropertyChanged事件对绑定更改作出反应,而您没有这些事件。将绑定到视图的任何内容实现INotifyPropertyChanged,然后在道具更改时触发事件,这样您就可以让绑定正常工作(单向或双向)

将您的模型更改为这样,它应该适合您


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}"/>


“这是我的ViewModel:”之后紧接着是ICommand的实现。我认为这可能只是一个编辑陷阱,但您可能希望轻推标题以指示哪些部分实际上是您的ViewModel。没有直接关系,但您希望在某处实现INotifyPropertyChanged-请参阅。这将通知视图对ViewModel中的属性所做的任何更改。“通常”的方法是创建一个基类,该基类实现INotifyPropertyChanged,然后在ViewModels中从中继承。我尝试了
公共类MyViewModel:INotifyPropertyChanged
,但它并没有像我希望的那样工作。我想在单击按钮时将TxtBox的内容复制到TxtBox2。我不确定第一个类如何不这样做。该操作将值从TxtBox复制到TxtBox2。您是否正在通过它来确保操作已启动(即,您的绑定是正确的)?
<TextBox Text="{Binding Model.TxtBox, Source={StaticResource viewModel}}" />
<TextBox Text="{Binding Model.TxtBox2, Source={StaticResource viewModel}}" />
<Button Command="{Binding ClickCommand}"/>