MVVM之INotifyPropertyChanged接口的几种实现方式(2)

方法二,使用Lambda表达式,静态扩展语法
public static class NotificationExtensions
{
public static void Notify(this PropertyChangedEventHandler eventHandler, Expression expression)
{
if( null == eventHandler )
{
return;
}
var lambda = expression 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 constantExpression = memberExpression.Expression as ConstantExpression;
var propertyInfo = memberExpression.Member as PropertyInfo;

        foreach (var del in eventHandler.GetInvocationList())
        {
            del.DynamicInvoke(new object[] {constantExpression.Value, new PropertyChangedEventArgs(propertyInfo.Name)});
        }
    }

}
这里用使用的静态扩展语法,我还是比较喜欢这个的,但是并不是所有人都喜欢哦。如何使用呢:
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);

   }

}

}
这里还可以添加一个很实用的扩展:
public static void SubscribeToChange(this T objectThatNotifies, Expression expression, PropertyChangedEventHandler handler)
where T : INotifyPropertyChanged
{
objectThatNotifies.PropertyChanged +=
(s, e) =>
{
var lambda = expression 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;

                    if(e.PropertyName.Equals(propertyInfo.Name))
                    {
                        handler(objectThatNotifies);
                    }
                };
    }

通过上面的代码,可以订阅熟悉改变事件,如:
myObject.SubscripeToChange(()=>myObject.SomeProperty,SomeProperty_Changed);
And then your handler would look like this:
private void SomeProperty_Changed(MyObject myObject)
{
/* … implement something here */
}
方法三,net4.5,框架提供的解决方法
private string m_myProperty;public string MyProperty
{
get { return m_myProperty; }
set
{
m_myProperty = value;
OnPropertyChanged();
}
}
private void OnPropertyChanged([CallerMemberName] string propertyName = “none passed”)
{
// … do stuff here …
}
属性CallerMemberName的解决办法和方法二是基本相同的,不同的是这个在net框架中解决的。更多信息可以查看CallerMemberName,net4.5还提供了
CallerFilePath,CallerLineNumber,这几很有用的语法
方法四,这个也不错哦
public static class SymbolExtensions
{
public static string GetPropertySymbol(this T obj, Expression> expr)
{
return ((MemberExpression)expr.Body).Member.Name;
}
}
public class ConversionOptions : INotifyPropertyChanged
{
private string _outputPath;
public string OutputPath
{
get { return _outputPath;}
set
{
_outputPath = value;
OnPropertyChanged(o => o.OutputPath);
}
}

    private string _blogName;
    public string BlogName
    {
        get { return _blogName;}
        set
        {
            _blogName = value;
            OnPropertyChanged(o => o.BlogName);
        }
    }

    private string _secretWord;
    public string SecretWord
    {
        get { return _secretWord; }
        set
        {
            _secretWord = value;
            OnPropertyChanged(o => o.SecretWord);
        }
    }


    protected virtual void OnPropertyChanged(Expression> propertyExpr)
    {
        OnPropertyChanged(this.GetPropertySymbol(propertyExpr));
    }

    protected virtual void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

   
    public event PropertyChangedEventHandler PropertyChanged;
}

你可能感兴趣的:(C#)