WPF MVVM 控件在其绑定的 VM 属性 更改时不会更新

WPF MVVM control won't update when its bound VM Property changes

我正在使用 Prism 框架编写一个 MVVM 应用程序。当 属性 值更改时,我无法更新标签。当我创建模型并将初始值分配给 属性 时,绑定到它的标签会更新。但是当我在应用程序生命周期内更改 属性 时,标签不会更新其内容。

这是我的 xaml:

<Window x:Class="Project.Views.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="700" Width="700">
    <DockPanel LastChildFill="True">
            <Button x:Name="btnStart" Command="{Binding Path=Start}" Content="StartProcess"/>

            <GroupBox Header="Current Operation">
                <Label x:Name="lblCurrentOperation" Content="{ Binding  CurrentOperationLabel, UpdateSourceTrigger=PropertyChanged}"/>
            </GroupBox>
    </DockPanel>
</Window>

这是我的视图模型:

public class MyModelViewModel : BindableBase
{
    private MyModel model;
    private string currentOpeartion;

    public DelegateCommand Start { get; private set; }

    public string CurrentOperationLabel
    {
        get { return currentOpeartion; }
        set { SetProperty(ref currentOpeartion, value); }
    }

    public MyModelViewModel ()
    {
        model = new MyModel ();

        Start  = new DelegateCommand (model.Start);
        CurrentOperationLabel = model.CurrentOperation; //Bind model to the ViewModel
    }   
}

在我的模型中,我在调用 "Start" 命令时更改了标签。

public class MyModel
{
    public string CurrentOperation { get; set; }

    public MyModel()
    {
        CurrentOperation = "aaa"; //This will make the label show "aaa"
    }

    public void Start()
    {
        CurrentOperation = "new label"; //This should alter the Label in the view, but it doesn't
    }
}

问题在于,在 Start 方法中,您修改了模型的 属性(即 CurrentOperation),而不是视图模型的 属性(即 CurrentOperationLabel). XAML 对模型一无所知,因为它绑定到视图模型。换句话说,当您修改 MyModel.CurrentOperation 属性 XAML 时,不会通知此事实。

要解决此问题,您应该更改代码的结构。更新模型后需要刷新视图模型。我的建议是这样修改MyModelViewModel

public class MyModelViewModel : BindableBase
{
      //...

      public void InnerStart()
      {
          model.Start();
          //Refresh the view model from the model
      }

      public MyModelViewModel ()
      {
        model = new MyModel ();

        Start  = InnerStart;
        CurrentOperationLabel = model.CurrentOperation; 
    }   
}

想法是按钮的点击应该在负责与模型通信的视图模型中处理。此外,它会根据模型的当前状态相应地更新属性。