自动INotifyPropertyChanged的 [英] Automatically INotifyPropertyChanged

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

问题描述

请问有什么办法可以自动获得通知的一类属性的更改,而无需在每一个二传手写OnPropertyChanged? (我有几百个属性,我想知道他们是否有改变)。

Is there any way to automatically get notified of property changes in a class without having to write OnPropertyChanged in every setter? (I have hundreds of properties that I want to know if they have changed).


安东建议<一href=\"http://www.nablasoft.com/alkampfer/index.php/2008/08/04/implement-inotifypropertychanged-with-castledynamicproxy/\">dynamic代理的。其实我已经使用了城堡库在过去类似的东西,虽然它确实会降低code,我不得不写的量,它增加了大约30秒,我的程序的启动时间(因人而异) - 因为它是一个运行时解决方案。

Anton suggests dynamic proxies. I've actually used the "Castle" library for something similar in the past, and while it does reduce the amount of code I've had to write, it added around 30 seconds to my program startup time (ymmv) - because it's a runtime solution.

我不知道是否有一个编译时的解决方案,可能使用编译时属性...

I'm wondering if there is a compile time solution, maybe using compile-time attributes...


Slashene和第三文化孩子给予产生重复code建议 - 不幸的是,不是所有的我的属性是m_Value =价值的一个简单的例子 - 其中很多定制code的制定者,让千篇一律的$ C从片段和XML $ c是不是我真正的项目无论是可行的。

Slashene and TcKs give suggestions which generates repetitive code - unfortunately, not all my properties are a simple case of m_Value = value - lots of them have custom code in the setters, so cookie-cutter code from snippets and xml aren't really feasible for my project either.

推荐答案

我们用下面的code(从的http://www.ingebrigtsen.info/post/2008/12/11/INotifyPropertyChanged-revisited.aspx).伟大的作品:)

The nameof operator was implemented in C# 6.0 with .NET 4.6 and VS2015 in July 2015. The following is still valid for C# < 6.0

We use the code below (From http://www.ingebrigtsen.info/post/2008/12/11/INotifyPropertyChanged-revisited.aspx). Works great :)

public static class NotificationExtensions
{
    #region Delegates

    /// <summary>
    /// A property changed handler without the property name.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="sender">The object that raised the event.</param>
    public delegate void PropertyChangedHandler<TSender>(TSender sender);

    #endregion

    /// <summary>
    /// Notifies listeners about a change.
    /// </summary>
    /// <param name="EventHandler">The event to raise.</param>
    /// <param name="Property">The property that changed.</param>
    public static void Notify(this PropertyChangedEventHandler EventHandler, Expression<Func<object>> Property)
    {
        // Check for null
        if (EventHandler == null)
            return;

        // Get property name
        var lambda = Property as LambdaExpression;
        MemberExpression memberExpression;
        if (lambda.Body is UnaryExpression)
        {
            var unaryExpression = lambda.Body as UnaryExpression;
            memberExpression = unaryExpression.Operand as MemberExpression;
        }
        else
        {
            memberExpression = lambda.Body as MemberExpression;
        }

        ConstantExpression constantExpression;
        if (memberExpression.Expression is UnaryExpression)
        {
            var unaryExpression = memberExpression.Expression as UnaryExpression;
            constantExpression = unaryExpression.Operand as ConstantExpression;
        }
        else
        {
            constantExpression = memberExpression.Expression as ConstantExpression;
        }

        var propertyInfo = memberExpression.Member as PropertyInfo;

        // Invoke event
        foreach (Delegate del in EventHandler.GetInvocationList())
        {
            del.DynamicInvoke(new[]
            {
                constantExpression.Value, new PropertyChangedEventArgs(propertyInfo.Name)
            });
        }
    }


    /// <summary>
    /// Subscribe to changes in an object implementing INotifiyPropertyChanged.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="ObjectThatNotifies">The object you are interested in.</param>
    /// <param name="Property">The property you are interested in.</param>
    /// <param name="Handler">The delegate that will handle the event.</param>
    public static void SubscribeToChange<T>(this T ObjectThatNotifies, Expression<Func<object>> Property, PropertyChangedHandler<T> Handler) where T : INotifyPropertyChanged
    {
        // Add a new PropertyChangedEventHandler
        ObjectThatNotifies.PropertyChanged += (s, e) =>
            {
                // Get name of Property
                var lambda = Property as LambdaExpression;
                MemberExpression memberExpression;
                if (lambda.Body is UnaryExpression)
                {
                    var unaryExpression = lambda.Body as UnaryExpression;
                    memberExpression = unaryExpression.Operand as MemberExpression;
                }
                else
                {
                    memberExpression = lambda.Body as MemberExpression;
                }
                var propertyInfo = memberExpression.Member as PropertyInfo;

                // Notify handler if PropertyName is the one we were interested in
                if (e.PropertyName.Equals(propertyInfo.Name))
                {
                    Handler(ObjectThatNotifies);
                }
            };
    }
}

用于例如这样的:

public class Employee : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    private string _firstName;
    public string FirstName
    {
        get { return this._firstName; }
        set
        {
            this._firstName = value;
            this.PropertyChanged.Notify(()=>this.FirstName);
        }
    }
}

private void firstName_PropertyChanged(Employee sender)
{
    Console.WriteLine(sender.FirstName);
}

employee = new Employee();
employee.SubscribeToChange(() => employee.FirstName, firstName_PropertyChanged);

在实施例的一些语法错误可能存在。没有测试它。但是你应该有概念,有至少:)

Some syntax errors in the example may exist. Didn't test it. But you should have the concept there at least :)

编辑:我现在明白,你可能是想就更少了工作,而且是啊...上面的东西,至少使得它容易得多。你prevent所有可怕的问题,指的是使用字符串属性。

I see now that you may have wanted even less work, but yeah... the stuff above at least makes it a lot easier. And you prevent all the scary problems with refering to properties using strings.

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

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