Riccardo Lomazzi Riccardo Lomazzi - 3 months ago 17
C# Question

A nicer way to handle Properties Changes in C#

I'm building a MVVM application in which a

ToBeListened
class has a couple of properties,
PropertyA
and
PropertyB
, and I want to listen to them.

public class ToBeListened : INotifyPropertyChanged
{

private double _propertyA;
private string _propertyB;
/*Here I'm omitting the update part where NotifyPropertyChanged gets called*/
public double PropertyA{get; set; }
public double PropertyB{get; set; }

public event PropertyChangedEventHandler PropertyChanged;

protected void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}


Those two properties are listened by a
Listener
class, so I've implemented an EventHandler in it, that listens to a
ToBeListened
object.

public class Listener
{

private ToBeListened toBeListenedObject;

public Listener()
{
toBeListenedObject = new ToBeListened();
toBeListenedObject.PropertyChanged += newPropertyChangedEventHandler(PropertyListener_PropertyChanged);
}

private void PropertyListener_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
switch(e.PropertyName)
{
case "PropertyA":
{
/*...DO SOMETHING...*/
}
case "PropertyB":
{
/*...Do something else...*/
}
}


The thing is, I don't really like this solution I've found. A
switch-case
isn't polymorphism-friendly, so


  1. is there a better way to do this? Maybe something that uses overloading? (Like
    private void PropertyListener_PropertyChanged(double sender, PropertyChangedEventArgs e)

  2. most of all, is it right to code a ViewModel like this?


Answer

I like Josh Smith's PropertyObserver, which you can get at http://mvvmfoundation.codeplex.com/ (some documentation from Josh at https://joshsmithonwpf.wordpress.com/2009/07/11/one-way-to-avoid-messy-propertychanged-event-handling/). It's a nice class that encapsulates the plumbing logic you're talking about, so you can focus on just handling changes to certain properties. So in your case, you could write code like:

var observer = new PropertyObserver<ToBeListened>(toBeListenedObject)
                  .RegisterHandler(tbl => tbl.PropertyA, tbl => HandlePropertyA(tbl))
                  .RegisterHandler(tbl => tbl.PropertyB, tbl => HandlePropertyB(tbl));

You can start using it by installing the MVVM Foundation nuget package into your solution. The ID is MvvmFoundation.Wpf.

Comments