C# WPF 如何动态设置属性的setter方法?

5

我一直在寻找,但似乎找不到我需要的内容,所以我决定在这里试试。

情况: 我有一个名为MainWindow和MainWindowData的类。在MainWindowData中,只定义了使用UpdateGUI属性的公共属性。

public class UpdateGUI : Attribute { }

public class MainWindowData
{
    [UpdateGUI]
    public string TESTVAR { get; set; }
}

现在我想为MainWindowData中的每个属性的setter方法添加一个方法。更具体地说:
void OnPropertyChanged(String PropertyName);

我想在MainWindow构造函数中获取所有UpdateGUI属性,然后以某种方式添加另一个方法,但这就是我卡住的地方。 我使用以下代码来获取所有属性,它可以正常工作:

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

这给了我一个很好的列表,列出了我需要更新的所有属性。
那么问题是:如何使这些属性动态转换为:
[UpdateGUI]
public string TESTVAR { get; set; }

to:

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

感谢您的帮助!非常感激 :)
问候

+1 有趣的问题,很期待看到结果。 - Avada Kedavra
3个回答

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; }
}

如果你不喜欢PostSharp,我相信其他AOP框架也有类似的功能。
编辑
我刚发现NotifyPropertyWeaver可以在不需要完整的AOP框架的情况下为您完成此操作。
它使用Mono.Cecil来在编译期间注入通知代码,并且可以通过NuGet(这就是我所做的)或项目网站安装。
默认情况下,它甚至不需要属性(它自动找出哪些属性和类需要更改通知),但您也可以显式指定,如下所示:
[NotifyProperty]
public int FooBar { get; set; }

我在其中发现的一个不错的功能是可以声明属性之间的依赖关系。在这种情况下,每当FooBar发生变化时,RaisePropertyChanged("FoobarTimesTwo")将被调用。
[DependsOn("FooBar")]
public int FoobarTimesTwo
{
    get { return FooBar * 2; }
}

+1 有趣的工作。如果有人想自己做这个工作,详细信息链接提供编码思路。 - Avada Kedavra
谢谢您的快速回复,那正是我所需要的。不幸的是它并非免费使用,但也许我可以弄清楚或找到其他AOP框架。 - Rik De Peuter

1

除了像PostSharp这样的AOP框架之外,还有以下这些东西:

Mono.Cecil

使用该工具,您可以获取一个程序集,修改其代码并保存回去

LinFu有一些关于AOP的文章可能会对您有所帮助

CodeProject上的LinFu文章


0

开源框架ImpromptuInterface.MVVM使用C# 4.0动态特性添加自动属性,支持属性更改。它的ImpromptuViewModel类似于ExpandoObject,但还具有其他功能,可帮助实现MVVM。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接