INotifyPropertyChanged与派生类

时间:2015-07-27 12:30:53

标签: wpf inotifypropertychanged

我有这堂课:

public class MyFileInfo : INotifyPropertyChanged
{
    private string _file;
    private int _bytesSent;

    public MyFileInfo(string file)
    {

    }

    public string File
    {
        get { return _file; }
        set { _file = value; }
    }

    public int BytesSent
    {
        get { return _bytesSent; }
        set { _bytesSent= value; }
    }
}

派生类:

public class MyFile : MyFileInfo
{

}

因此,每当我的_bytesSent发生变化时,我都要通知:

public event PropertyChangedEventHandler PropertyChanged;

public virtual void NotifyPropertyChange(string propertyName)
{
    var handler = PropertyChanged;
    if (handler != null)
        handler(this, new PropertyChangedEventArgs(propertyName));
}

使用此:

public static int PropertyName
{
    get { return _propertyName; }
    set
    {
        _totalPacketsSent = value;
        NotifyPropertyChange("...");
    }
}

所以我的问题是:我应该在哪里宣布这个事件?在派生的基类中

3 个答案:

答案 0 :(得分:2)

按照惯例,您应该在基类中将其定义为受保护的虚拟名称"在 EventName ":

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

答案 1 :(得分:0)

基类,它应该正常工作。还有一件事,将你的方法改为:

public virtual void NotifyPropertyChange([CallerMemberName]string propertyName = null)
{
    PropertyChanged?.Invoke (this, new PropertyChangedEventArgs (propertyName));
}

这样,您可以调用它而不指定属性名称,如下所示:

NotifyPropertyChange ();

编译器将为您填写属性名称。您仍然可以指定属性:

NotifyPropertyChange ("Property");
NotifyPropertyChange (nameof (Property));

正如Liero所说,你应该使用标准的命名OnPropertyChanged方案。 注意:? (安全导航操作员)和名称仅在C#6中可用。

然后,每当您希望属性通知UI它已更改时,您执行以下操作:

public String MyTestProperty
{
    get {return _MyTestProperty;}
    set {
        _MyTestProperty = value;
        NotifyPropertyChange ();
    }
}

答案 2 :(得分:0)

有一个基类可以累积一些与INotifyPropertyChanged相关的有用操作,这可能不会有什么坏处。我通常使用类似于以下内容的东西:

public class NotifiableBase : INotifyPropertyChanged
    {
        #region Utility methods

        /// <summary>
        /// Notify of a property change and optional additional dependencies.
        /// </summary>
        public void Notify([CallerMemberName] string propertyName = null, params string[] additionalNames)
        {
            OnPropertyChanged(propertyName);
            foreach (var name in additionalNames)
            {
                OnPropertyChanged(name);
            }
        }

        /// <summary>
        /// Makes a change to the supplied reference if different.
        /// If different, notify of a property change and optional additional dependencies.
        /// </summary>
        public bool ChangeAndNotify<T>(ref T toChange, T newValue, [CallerMemberName] string propertyName = null, params string[] additionalNames)
        {
            var cmp = EqualityComparer<T>.Default;
            if (cmp.Equals(toChange, newValue) == false)
            {
                toChange = newValue;
                OnPropertyChanged(propertyName);
                foreach (var name in additionalNames)
                {
                    OnPropertyChanged(name);
                }
                return true;
            }
            return false;
        }

        /// <summary>
        /// Makes a change to the supplied reference if different.
        /// If different, notify of a property change and optional additional dependencies then call action.
        /// </summary>
        public bool ChangeAndNotifyWithAction<T>(ref T toChange, T newValue, Action action, [CallerMemberName] string propertyName = null, params string[] additionalNames)
        {
            var ret = ChangeAndNotify(ref toChange, newValue, propertyName, additionalNames);
            if (ret)
            {
                action();
            }
            return ret;
        }

        #endregion

        #region INotifyPropertyChanged implementation

        public event PropertyChangedEventHandler PropertyChanged;

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

        #endregion
    }

这些调用的样式允许您在一行中执行大部分操作:

public int PropertyName
{
    get { return _propertyName; }
    set { ChangeAndNotify(ref _propertyName, value); }
}

public int PropertyName
{
    get { return _propertyName; }
    set { ChangeAndNotify(ref _propertyName, value, "PropertyName", "AdditionalRelatedPropertyName"); }
}

public int PropertyName
{
    get { return _propertyName; }
    set { ChangeAndNotify(ref _propertyName, value, () => SomeActionOnSuccess()); }
}