6

我发现我经常重复自己,这当然不好。所以我想知道我是否可以为此做点什么。这是我的 WPF 应用程序中的常见代码:

private string _name;
public string Name
{
    get { return _name; }
    set
    {
        if (_name != value)
        {
            _name = value;
            OnPropertyChanged("Name");
        }
    }
}

所以我想知道我是否可以以某种方式包装 setter 以使其更好、更具可读性。一个想法是这样的:

protected void PropertySetter<T>(T property, T value, string name)
{
    if (EqualityComparer<T>.Default.Equals(property, value))
    {
        property = value;
        OnPropertyChanged(name);
    }
}

像这样的用法:

private string _name2;
public string Name2
{
    get { return _name2; }
    set
    {
        PropertySetter<string>(Name2, value, "Name2");
    }
}

但我不确定这是否真的很聪明,或者是否适用于值类型?

我想我不是第一个尝试这样的事情的人,所以如果有人知道这样的事情的一个很好的万无一失的方法,请插话。我想我不能在没有反射的情况下使 propertyChanged 类型安全,但那里的任何想法也会有所帮助。

4

2 回答 2

2

也许这可以帮助你

public class ObservableObject : INotifyPropertyChanged
{
    #region Events
    public event PropertyChangedEventHandler PropertyChanged;
    #endregion

    #region Protected Methods
    protected virtual void SetAndNotify<T>(ref T field, T value, Expression<Func<T>> property)
    {
        if (!object.ReferenceEquals(field, value))
        {
            field = value;
            this.OnPropertyChanged(property);
        }
    }

    protected virtual void OnPropertyChanged<T>(Expression<Func<T>> changedProperty)
    {
        if (PropertyChanged != null)
        {
            string name = ((MemberExpression)changedProperty.Body).Member.Name;
            PropertyChanged(this, new PropertyChangedEventArgs(name));
        }
    }
    #endregion
}

用法:

private String _myField;
    public String MyProperty
    {
        get
        { return _myField; }
        set
        { SetAndNotify(ref _myField, value, () => MyProperty); }
    }

编辑:您的类必须继承自OservableObject此类

于 2012-06-18T16:01:30.603 回答
2

是的 - 这是完全可以接受的正常代码。

这是我发现的一个非常标准化的示例(我在代码示例中看到了很多这种类型的用法)。

public event PropertyChangedEventHandler PropertyChanged;

private void SetProperty<T>(ref T field, T value, string name)
{
    if (!EqualityComparer<T>.Default.Equals(field, value))
    {
        field = value;
        var handler = PropertyChanged;
        if (handler != null)
        {
          handler(this, new PropertyChangedEventArgs(name));
        }
    }
}

将此代码包装在实现的类中INotifyPropertyChanged,并从此类继承您的数据对象。

在您的示例中,您直接调用事件 -永远不要这样做。从方法开始到调用事件时,您可能会丢失事件引用。总是在调用它之前创建事件的本地缓存。

于 2012-06-18T16:03:04.087 回答