简体   繁体   中英

PropertyChanged WPF MVVM Light

I am using MVVM light in WPF. The Model class properties are constantly changed due to changes of the underlying data-access layer.

Model:

public class SBE_V1_Model : ViewModelBase
{
    public SBE_V1_Model(String name)
    {
        Name = "MAIN." + name;
        SetupClient();
    }
    private void SetupClient()
    {
        client =  new ConnectionHelper(this);
        client.Connect(Name);

    }
    public Boolean Output
    {
        get
        {
            return _Output;
        }
        set
        {
            if (value != this._Output)
            {
                Boolean oldValue = _Output;
                _Output = value;
                RaisePropertyChanged("Output", oldValue, value, true);
            }
        }
    }
}

If Output property changes, then bindings will be notified, so this works. But what is the correct way to update the property from the data-access source, which knows the new value?

public class ConnectionHelper : ViewModelBase
{
   public Boolean Connect(String name)
    {
        Name = name;
        tcClient = new TcAdsClient();

        try
        {
            dataStream = new AdsStream(4);
            binReader = new AdsBinaryReader(dataStream);
            tcClient.Connect(851);
            SetupADSNotifications();
            return true;
        }
        catch (Exception ee)
        {
            return false;
        }
    }
    private void tcClient_OnNotification(object sender, AdsNotificationEventArgs e)
    {
        String prop;
        notifications.TryGetValue(e.NotificationHandle, out prop);
        switch (prop)
        {
            case "Output":
                Boolean b = binReader.ReadBoolean();
                RaisePropertyChanged("Output", false,b, true);
                break;
     }
   }
 }

Why doesnt the RaisePropertyChanged call in connectionhelper update the property of the model? If this is the wrong way, should I set up some kind of listener?

You should only use PropertyChanged in the view model, not at the Model. You can use PropertyChange in Model only in special times.

RaisePropertyChanged("Output", false,b, true);

In that PropertyChanged you are alwais saying that Output Property was changed.

I recommend you to implements INotifyPropertyChanged

class MyClass : INotifyPropertyChanged
    {
      public bool MyProperty{ get; set; }

      public event PropertyChangedEventHandler PropertyChanged;

      protected void OnPropertyChanged(string name)
      {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
          handler(this, new PropertyChangedEventArgs(name));
         }
      }

    }

To notify any property change you have to use:

OnPropertyChanged("MyProperty");

In your SBE_V1_Model class you should subscribe to receive PropertyChange notifications from the ConnectionHelper ViewModel.

// Attach EventHandler
ConnectionHelper.PropertyChanged += OnConnectionHelperPropertyChanged;

...

// When property gets changed, raise the PropertyChanged 
// event of the ViewModel copy of the property
OnConnectionHelperPropertyChanged(object sender, PropertyChangedEventArgs e)
{
    if (e.PropertyName == "Something") //your ConnectionHelper property name
        RaisePropertyChanged("Ouput");
}

Also look into MVVM light messenger. Here is a link you might be interested from StackOverflow.

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