简单的小INotifyPropertyChanged实现 [英] Simple small INotifyPropertyChanged implementation

查看:151
本文介绍了简单的小INotifyPropertyChanged实现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

说我有以下课程:

public MainFormViewModel
{
    public String StatusText {get; set;}
}

将对StatusText的更改反映到与其绑定的任何控件中,最简单的最小方法是什么?

What is the easiest smallest way to get my changes to StatusText to reflect to any controls that bind to it?

很明显,我需要使用INotifyPropertyChanged,但是有没有一种很酷的方法来使我的代码不混乱?需要大量文件?等等?

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?

注意:如果这是骗子,那么我很抱歉.我进行了搜索,但没有找到任何东西,只是使用了 T4代码生成听起来不容易(至少要设置).

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).

推荐答案

不幸的是,C#没有提供一种简单的机制来自动执行此操作...它已经

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...

一种可能的解决方案是使用AOP框架,例如 Postsharp ,那样,您只需要装饰自己的属性的属性:

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

(还没有尝试过,但是我很确定Postsharp允许您做这种事情...)

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

请注意,您的类仍需要实现INotifyPropertyChanged接口.您只是不必在属性设置器中显式引发该事件.

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.

这篇关于简单的小INotifyPropertyChanged实现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆