如何提高PropertyChanged事件,而无需使用字符串名称 [英] How to raise PropertyChanged event without using string name

查看:290
本文介绍了如何提高PropertyChanged事件,而无需使用字符串名称的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这将是件好事,提高的PropertyChanged'事件没有明确的规定更改属性的名称能力。我愿做这样的事情:

It would be good to have ability to raise 'PropertyChanged' event without explicit specifying the name of changed property. I would like to do something like this:

    public string MyString
    {
        get { return _myString; }
        set
        {
            ChangePropertyAndNotify<string>(val=>_myString=val, value);
        }
    }

    private void ChangePropertyAndNotify<T>(Action<T> setter, T value)
    {
        setter(value);
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(setter.Method.Name));
        }
    }

在这种情况下,接收到的名字是λ-方法的名称:&LT; set_MyString> b__0

In this case received name is a name of lambda-method: "<set_MyString>b__0".

  1. 我可以肯定,即微调&LT; SET_?和> b__0永远提供正确的属性名称
  2. 是否有任何其他通知有关产权变更(由物业自己)?

感谢你。

推荐答案

更新:原来的code不是的Windows Phone友好的,因为它依赖于LambdaEx pression.Compile( ),以获取事件源对象。下面是更新扩展方法(有参数检查删除以及):

Update: The original code is not Windows Phone friendly, as it relies on LambdaExpression.Compile() to get the event source object. Here's the updated extension method (with parameter checks removed as well):

    public static void Raise<T>(this PropertyChangedEventHandler handler, Expression<Func<T>> propertyExpression)
    {
        if (handler != null)
        {
            var body = propertyExpression.Body as MemberExpression;
            var expression = body.Expression as ConstantExpression;
            handler(expression.Value, new PropertyChangedEventArgs(body.Member.Name));
        }
    }

用法保持如下。

The usage stays as below.

您可以使用反射在lambda函数调用的属性getter获得属性名。请注意,你实际上并不需要调用该拉姆达,你只需要它的思考:

You can get the property name using reflection on a lambda function that calls the property getter. note that you don't actually have to invoke that lambda, you just need it for the reflection:

public static class INotifyPropertyChangedHelper
{
    public static void Raise<T>(this PropertyChangedEventHandler handler, Expression<Func<T>> propertyExpression)
    {
        if (handler != null)
        {
            var body = propertyExpression.Body as MemberExpression;
            if (body == null)
                throw new ArgumentException("'propertyExpression' should be a member expression");

            var expression = body.Expression as ConstantExpression;
            if (expression == null)
                throw new ArgumentException("'propertyExpression' body should be a constant expression");

            object target = Expression.Lambda(expression).Compile().DynamicInvoke();

            var e = new PropertyChangedEventArgs(body.Member.Name);
            handler(target, e);
        }
    }

    public static void Raise<T>(this PropertyChangedEventHandler handler, params Expression<Func<T>>[] propertyExpressions)
    {
        foreach (var propertyExpression in propertyExpressions)
        {
            handler.Raise<T>(propertyExpression);
        }
    }
}

下面是如何使用该助手在你的类引发事件的一个或多个属性:

Here's how you can use that helper in your class to raise the event for one or multiple properties:

PropertyChanged.Raise(() => this.Now);
PropertyChanged.Raise(() => this.Age, () => this.Weight);

请注意,这个助手也无操作的情况下,的PropertyChanged

Note that this helper also is a no-op in case the PropertyChanged is null.

这篇关于如何提高PropertyChanged事件,而无需使用字符串名称的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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