问题
I've been searching around but I just can't seem to find what I'm looking for, so I'll give it a go here.
Situation: I have the class MainWindow and MainWindowData. In MainWindowData are only public properties defined with the attribute UpdateGUI.
public class UpdateGUI : Attribute { }
public class MainWindowData
{
[UpdateGUI]
public string TESTVAR { get; set; }
}
Now I want to add a method to each property's setter method in MainWindowData. More specific:
void OnPropertyChanged(String PropertyName);
I figured I'd fetch all UpdateGUI properties in the MainWindow constructor, and then somehow add another method to it, but this is where I'm stuck. I use this code to fetch all properties, which works:
List<PropertyInfo> properties = (from pi in typeof(MainWindowData).GetProperties()
where pi.GetCustomAttributes(typeof(UpdateGUI), false).Any()
select pi).ToList();
This gives me a nice list of all properties that I have to update.
So the question is: how can I make it so that the properties dynamically get transformed from:
[UpdateGUI]
public string TESTVAR { get; set; }
to:
[UpdateGUI]
private string _TESTVAR;
public string TESTVAR {
get {
return _TESTVAR;
}
set {
_TESTVAR = value;
OnPropertyChanged("TESTVAR");
}
}
Thank you for any help! It will be highly appreciated :)
Greetings
回答1:
What you are looking for has been solved in the concept of Aspect Oriented Programming (AOP).
One example is in PostSharp, (Also, see details here) which lets you write your data/viewmodel classes like this:
[NotifyPropertyChanged]
public class Shape
{
public double X { get; set; }
public double Y { get; set; }
}
public class Rectangle : Shape
{
public double Width { get; set; }
public double Height { get; set; }
}
If you don't like PostSharp, I'm sure the other AOP frameworks out there has similar functionality.
EDIT
I just found NotifyPropertyWeaver which does this for you without requiring a full AOP framework.
It uses the Mono.Cecil stuff to inject notification code during compilation and is installable either through NuGet (this is what I did) or from the project web site.
By default, it doesn't even require attributes, (it automatically figures out which properties and classes need change notification) but you can be explicit also, like so:
[NotifyProperty]
public int FooBar { get; set; }
One nice feature I found in it was the possibility to declare dependencies between properties. In this case, RaisePropertyChanged("FoobarTimesTwo")
will be called whenever FooBar changes.
[DependsOn("FooBar")]
public int FoobarTimesTwo
{
get { return FooBar * 2; }
}
回答2:
In addition to AOP frameworks like PostSharp there are also such things as:
Mono.Cecil
With that tool you can take an assembly, modify it's code and save it back
There are some articles of LinFu about AOP which may help
LinFu Articles on CodeProject
回答3:
The open source framework ImpromptuInterface.MVVM uses the C# 4.0 dynamic features to add automatic properties that support property changed. It's ImpromptuViewModel works like an ExpandoObject but also has other features to help with MVVM.
来源:https://stackoverflow.com/questions/6408469/c-sharp-wpf-how-to-set-property-setter-method-dynamically