简体   繁体   中英

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

I'm writing an MVVM application using Prism Framework. I can't make my label update when the property value changes. When I create the model and assign initial value to the Property, the lable bound to it gets updated. But then when I change the Property during application lifetime, the label won't update its content.

Here is my 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>

Here is my ViewModel:

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

And in my Model, I change the label when the "Start" command is invoked.

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

The problem is that in Start method you modifies a property of a model (ie CurrentOperation ) and not a property of a view model (ie CurrentOperationLabel ). XAML knows nothing about model because it is bound to a view model. In other words when you modify MyModel.CurrentOperation property XAML is not notified about this fact.

To fix this problem you should change the structure of your code. You need to refresh a view model after updating a model. My suggestion is to modify MyModelViewModel in this way:

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; 
    }   
}

The idea is that button's clicks should be handled in the view model which is responsible for the communication with the model. Additionally it updates properties accordingly based on the current state of the model.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM