我有这堂课:
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("...");
}
}
所以我的问题是:我应该在哪里宣布这个事件?在派生的基类中
答案 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()); }
}