C#WPF如何动态设置Property setter方法?

Rik*_*ter 5 c# methods setter properties dynamic

我一直在寻找,但我似乎无法找到我正在寻找的东西,所以我会在这里试一试.

情况:我有MainWindow和MainWindowData类.在MainWindowData中,只有使用属性UpdateGUI定义的公共属性.

public class UpdateGUI : Attribute { }

public class MainWindowData
{
    [UpdateGUI]
    public string TESTVAR { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

现在我想在MainWindowData中为每个属性的setter方法添加一个方法.更加具体:

void OnPropertyChanged(String PropertyName);
Run Code Online (Sandbox Code Playgroud)

我想我会在MainWindow构造函数中获取所有UpdateGUI属性,然后以某种方式添加另一个方法,但这就是我被困住的地方.我使用此代码来获取所有属性,其工作原理:

List<PropertyInfo> properties = (from pi in typeof(MainWindowData).GetProperties()
                                 where pi.GetCustomAttributes(typeof(UpdateGUI), false).Any()
                                 select pi).ToList();
Run Code Online (Sandbox Code Playgroud)

这给了我一个很好的列表,列出了我必须更新的所有属性.

所以问题是:我怎样才能使属性动态地从以下变换:

[UpdateGUI]
public string TESTVAR { get; set; }
Run Code Online (Sandbox Code Playgroud)

至:

[UpdateGUI]
private string _TESTVAR;
public string TESTVAR { 
    get {
        return _TESTVAR;
    }
    set {
        _TESTVAR = value;
        OnPropertyChanged("TESTVAR");
    }
}
Run Code Online (Sandbox Code Playgroud)

感谢您的任何帮助!非常感谢:)

问候

Isa*_*avo 5

您正在寻找的内容已经在面向方面编程(AOP)的概念中得到了解决.

一个例子是PostSharp,(另请参见此处的详细信息),它允许您编写数据/视图模型类,如下所示:

[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; }
}
Run Code Online (Sandbox Code Playgroud)

如果您不喜欢PostSharp,我确信其他AOP框架具有类似的功能.

编辑

我刚刚发现NotifyPropertyWeaver为你做这个,而不需要一个完整的AOP框架.

它使用Mono.Cecil的东西在编译期间注入通知代码,并且可以通过NuGet(这是我做的)或从项目网站安装.

默认情况下,它甚至不需要属性(它会自动确定哪些属性和类需要更改通知),但您也可以显式,如下所示:

[NotifyProperty]
public int FooBar { get; set; }
Run Code Online (Sandbox Code Playgroud)

我在其中发现的一个很好的功能是可以声明属性之间的依赖关系.在这种情况下,RaisePropertyChanged("FoobarTimesTwo")只要FooBar发生变化,就会调用它.

[DependsOn("FooBar")]
public int FoobarTimesTwo
{
    get { return FooBar * 2; }
}
Run Code Online (Sandbox Code Playgroud)