C# WPF MVVM控制赢得';t在其绑定的VM属性更改时更新

C# WPF MVVM控制赢得';t在其绑定的VM属性更改时更新,c#,wpf,mvvm,prism,C#,Wpf,Mvvm,Prism,我正在使用Prism框架编写一个MVVM应用程序。属性值更改时,我无法更新标签。当我创建模型并为属性指定初始值时,绑定到该属性的标签将更新。但是,当我在应用程序生命周期内更改属性时,标签将不会更新其内容 这是我的xaml: <Window x:Class="Project.Views.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="h

我正在使用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>
在我的模型中,我在调用“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
property时,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; 
    }   
}

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

问题在于,在
Start
方法中,您修改了模型的属性(即
CurrentOperation
),而不是视图模型的属性(即
CurrentOperationLabel
)。XAML对模型一无所知,因为它绑定到视图模型。换句话说,当您修改
MyModel.CurrentOperation
property时,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; 
    }   
}

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

您显示的代码没有实现INotifyPropertyChanged,我假设这是在未提供的BindableBase中。您可以添加该代码吗?在调用
Start()时,尝试在
CurrentOperationLabel
的setter处设置断点
model类的方法,并查看新值“new label”是否出现。我最初的怀疑是,您的start方法正在更改模型,而不是viewModel,因此视图模型不知道其已更改,因此无法通知您注释“将模型绑定到viewModel”的位置,这不是您要做的。您只是将当前值复制到视图模型中,它从未更新过。@MikeT
BindableBase
确实实现了INPC,如果值不同,
SetProperty
将导致引发事件。您显示的代码没有实现INotifyPropertyChanged,我假设这是在未提供的BindableBase中,可以吗添加代码?调用
Start()时,尝试在
CurrentOperationLabel
的setter处设置断点
model类的方法,并查看新值“new label”是否出现。我最初的怀疑是,您的start方法正在更改模型,而不是viewModel,因此视图模型不知道其已更改,因此无法通知您注释“将模型绑定到viewModel”的位置,这不是您要做的。您只是将当前值复制到视图模型中,它从未更新过。@MikeT
BindableBase
确实实现了INPC,如果值不同,
SetProperty
将导致引发事件。是的,您说得对。然后我应该如何通知ViewModel,该模型的属性已更改?我不介意你修改我的代码:)是的,你说得对。然后我应该如何通知ViewModel,该模型的属性已更改?我不介意你修改我的代码:)