Say I have the following class:
public MainFormViewModel
{
public String StatusText {get; set;}
}
What is the easiest smallest way to get my changes to StatusText to reflect to any controls that bind to it?
Obviously I need to use INotifyPropertyChanged, but is there a cool way to do it that does not clutter up my code? need lots of files? etc?
Note: If this is a dupe then I am sorry. I searched and could not find any thing but using T4 code Generation which does not sound easy (to setup at least).
Unfortunately C# doesn't offer an easy mechanism to do that automatically... It has been suggested to create a new syntax like this :
public observable int Foo { get; set; }
But I doubt it will ever be included in the language...
A possible solution would to use an AOP framework like Postsharp, that way you just need to decorate your properties with an attribute:
public MainFormViewModel : INotifyPropertyChanged
{
[NotifyPropertyChanged]
public String StatusText {get; set;}
}
(haven't tried, but I'm pretty sure Postsharp allows you to do that kind of thing...)
UPDATE: OK, I managed to make it work. Note that it's a very crude implementation, using reflection on a private field to retrieve the delegate... It could certainly be improved, but I'll leave it to you ;)
[Serializable]
public class NotifyPropertyChangedAttribute : LocationInterceptionAspect
{
public override void OnSetValue(LocationInterceptionArgs args)
{
object oldValue = args.GetCurrentValue();
object newValue = args.Value;
base.OnSetValue(args);
if (args.Instance is INotifyPropertyChanged)
{
if (!Equals(oldValue, newValue))
{
RaisePropertyChanged(args.Instance, args.LocationName);
}
}
}
private void RaisePropertyChanged(object instance, string propertyName)
{
PropertyChangedEventHandler handler = GetPropertyChangedHandler(instance);
if (handler != null)
handler(instance, new PropertyChangedEventArgs(propertyName));
}
private PropertyChangedEventHandler GetPropertyChangedHandler(object instance)
{
Type type = instance.GetType().GetEvent("PropertyChanged").DeclaringType;
FieldInfo propertyChanged = type.GetField("PropertyChanged",
BindingFlags.Instance | BindingFlags.NonPublic);
if (propertyChanged != null)
return propertyChanged.GetValue(instance) as PropertyChangedEventHandler;
return null;
}
}
Note that your class still need to implement the INotifyPropertyChanged
interface. You just don't have to explicitly raise the event in your property setters.
Have a go of this http://code.google.com/p/notifypropertyweaver/
All you need to do is implement INotifyPropertyChanged
So your code will look like
public MainFormViewModel : INotifyPropertyChanged
{
public String StatusText {get; set;}
#region INotifyPropertyChanged Implementation
}
The build task will compile this (you never see the below code)
public MainFormViewModel : INotifyPropertyChanged
{
public String StatusText {get; set;}
private string statusText;
public string StatusText
{
get { return statusText; }
set
{
if (value!= statusText)
{
statusText = value;
OnPropertyChanged("StatusText");
}
}
}
#region INotifyPropertyChanged Implementation
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With