我已经对管理 propertychanged 通知进行了自己的实现调整。
第一部分是经典的 NotifierBase 类:
/// <summary>
/// Base class for all notifying objects (model adapters, view models, etc.)
/// </summary>
public abstract class NotifierBase : INotifyPropertyChanged
{
/// <summary>
/// Private reference to UI thread
/// </summary>
private readonly System.Windows.Threading.Dispatcher _uiThread;
/// <summary>
/// Default Constructor
/// </summary>
protected NotifierBase()
{
_uiThread = Application.Current != null ? Application.Current.Dispatcher : System.Windows.Threading.Dispatcher.CurrentDispatcher;
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion
/// <summary>
/// Explicit raise of a property changed notification
/// </summary>
/// <param name="e"> </param>
protected void Notify(PropertyChangedEventArgs e)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
//Debug method used to verify that the property we are about to raise is really a member of the current class instance
CheckProperty(e.PropertyName);
//raises the notification
ToUiThread(() => handler(this, e));
}
}
protected void Notify(params PropertyChangedEventArgs[] e)
{
foreach (var pcea in e)
{
Notify(pcea);
}
}
/// <summary>
/// Dispatch an action to the ui thread
/// </summary>
/// <param name="action"> Action to dispatch </param>
protected void ToUiThread(Action action)
{
if (_uiThread.CheckAccess()) //if we are already in the UI thread, invoke action
action();
else
{
//otherwise dispatch in the ui thread
_uiThread.Invoke(action);
}
}
/// <summary>
/// Check if the raised property is a valid property for the current instance type
/// </summary>
/// <param name="propertyName"> Name of the raised property </param>
[DebuggerStepThrough]
private void CheckProperty(string propertyName)
{
Type type = GetType();
PropertyInfo[] properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public);
if (properties.Any(pi => pi.Name == propertyName)) return;
throw new InvalidOperationException(
string.Format("Trying to raise notification on property \"{0}\" which does not exists on type \"{1}\"",
propertyName, type.Name));
}
}
基本上,此类提供: - 一个简单的 UI 线程调度功能 - 对通知的属性进行调试检查 - 多属性通知功能
第二部分是集中类,它重新组合了我的应用程序中使用的所有通知事件参数。如果一个属性被多次使用,这主要是避免在整个应用程序中使用多个相同的硬编码字符串。但是对于代码重构来说,一般来说,可维护性也更容易。
public class Npcea
{
public static readonly PropertyChangedEventArgs BarCode = new PropertyChangedEventArgs("BarCode");
public static readonly PropertyChangedEventArgs Cap = new PropertyChangedEventArgs("Cap");
public static readonly PropertyChangedEventArgs Code = new PropertyChangedEventArgs("Code");
public static readonly PropertyChangedEventArgs Status = new PropertyChangedEventArgs("Status");
public static readonly PropertyChangedEventArgs Comments = new PropertyChangedEventArgs("Comments");
}
所以基本上,在您的视图模型(或适配器或其他)中,您只需通知这样的属性
public ResourceStatus Status
{
get { return _status; }
set
{
_status = value;
Notify(Npcea.Status,Npcea.Comments);
}
}
希望这会有所帮助
- 布鲁诺