使用Button_Click事件使用MVVM更改文本框内容

时间:2014-06-23 00:49:48

标签: c# wpf mvvm

我甚至不知道这是否是正确的标题,但无论如何。我正在从WinForms切换并尝试学习WPF和MVVM方法。

我有一个自定义类Incident,用于存储我的团队必须响应的事件数据。我正在构建一个View,以便将该类的实例中的数据显示给用户,并允许该用户对其进行操作。需要显示多个DateTime数据 - StartEndNotification_ReceivedActions_Taken。我需要一个小按钮,将DateTime.Now放入每个关联的TextBox,并更改当前加载的Incident类实例的基础值。

我正在试图弄清楚如何做到这一点。使用WinForms,我只需在同一个TextBox.Text函数中将Incident.StartDateTime.Now(等)设置为Button_Click,但我对MVVM的理解是我是不应该这样做,而是我应该将TextBox绑定到VM并更新VM的值。

这就是我被困住的地方。我很确定我很擅长如何进行绑定,但不是我从Button_Click函数更改VM值的部分。请帮忙吗?

2 个答案:

答案 0 :(得分:1)

你是对的 - 视图模型应该控制更改,文本框应该通过绑定进行更新。

在MVVM模式中,很少使用代码隐藏。您需要命令绑定,而不是Button_Click方法:

<Button Command="{Binding SetAllDatesToNowCommand}"/>

按下按钮时将执行该命令。 SetAllDatesToNowCommand是一个命令处理程序 - 它应该是视图模型上的ICommand属性:

public ICommand SetAllDatesToNowCommand { get; private set; }

我通常倾向于使用MVVM Light Toolkit中的RelayCommand来创建命令处理程序,因为语法干净且非常简单。命令处理程序在视图模型的构造函数中初始化。传递给RelayCommand的处理程序方法是您应该在所选Incident对象上设置属性的地方:

public YourViewModel()
{
    this.SetAllDatesToNowCommand =
        new RelayCommand(this.ExecuteSetAllDatesToNowCommand);
}

...

public void ExecuteSetAllDatesToNowCommand()
{
    this.selectedIncident.Start = DateTime.Now;
    // etc.
}

如果正确设置了文本框上的绑定,并且正在设置的属性正在触发相应的PropertyChanged事件,则应在命令执行方法中设置属性时更新它们。

但是,我建议你应该有Incident的视图模型,它实现了INotifyPropertyChanged接口。上面概述的命令将是该视图模型的属性。例如,设置该视图模型上的Start属性应该在Incident对象上设置它作为(“模型”对象)的视图模型的属性,并且还应该引发{ {1}}事件。否则,您的PropertyChanged类必须实现Incident,并且模型和视图模型类之间的界限变得不那么清晰。

答案 1 :(得分:0)

我假设您已将表单绑定到ViewModel。因此,ViewModel中的属性为Start。您想要将字段绑定到该

<TextBlock Text={Binding Start}/>

<TextBlock Text={Binding Incident.Start}/>

取决于您如何公开事件。要更新Start,您必须做两件事。使用按钮上的命令。

<Button Command="{Binding TestCommand}">Test</Button>

在ViewModel中,您可以定义命令。

private RelayCommand _testCommand;
public RelayCommand TestCommand
{
    get
    {
        return _testCommand ?? (_testCommand = new RelayCommand(TestUpdate, CanRunTest));
    }
    set
    {
        if (_testCommand == value) return;
        _testCommand = value;
    }
}


public bool CanRunTest()
{
    return some boolean test that defines if the command can run now;
}

private void TestUpdate()
{
     Incident.Start = DateTime.Now;
}

RelayCommand是一个可以在MVVMLight中找到的辅助方法。有关RelayCommand的信息,请参阅Josh Smith。

其次,您需要在事件模型上实现INotifyPropertyChanged或查找ObservableObject并使您的Start属性看起来像这样。

public class Incident : ObservableObject
{
    private ObservableCollection<WordLetter> _start;
    public virtual ObservableCollection<WordLetter> Start
    {
        get { return _start; }
        set
        {
            if (value == _start) return;
            _start = value;
            NotifyPropertyChanged();
        }
    }
}