C# WPF How to set Property setter method dynamically?

和自甴很熟 提交于 2019-12-22 06:59:13

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!