Reputation: 1836
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
private void PropertyListener_PropertyChanged(double sender, PropertyChangedEventArgs e)
Upvotes: 4
Views: 1426
Reputation: 11840
In the past I've used a little class derived from Dictionary<string, Action>
for this purpose. It was something like this:
public class PropertyChangedHandler : Dictionary<string, Action>
{
public PropertyChangedHandler(INotifyPropertyChanged source)
{
source.PropertyChanged += Source_PropertyChanged;
}
private void Source_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
Action toDo;
if (TryGetValue(e.PropertyName, out toDo))
{
toDo();
}
}
}
Then your listener looks like this:
public class Listener
{
private ToBeListened toBeListenedObject = new ToBeListened();
PropertyChangedHandler handler;
public Listener()
{
handler = new PropertyChangedHandler(toBeListenedObject)
{
{ "PropertyA", DoA },
{ "PropertyB", DoB }
};
}
private void DoB()
{
}
private void DoA()
{
}
}
This is just an example to give you an idea - it can be expanded for more complex purposes, of course.
Upvotes: 1
Reputation: 3889
i think MVVM Light framework (or library?) has what you need. Take a look at their ObservableObject
class http://www.mvvmlight.net/help/SL5/html/d457231f-6af7-601d-fa1f-1fe7c9f60c57.htm
Basically what it does, is making your object observable.
Upvotes: 0
Reputation: 887
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.
Upvotes: 4