我對TheGateKeeper的最終解決方案採取了類似的方法。但是我綁定了許多不同的對象。所以我需要一些更通用的東西。解決方案是創建一個實現了ICustomTypeDescriptor的包裝器。通過這種方式,我不需要爲可以在UI中顯示的所有內容創建包裝屬性。
public class SynchronizedNotifyPropertyChanged<T> : INotifyPropertyChanged, ICustomTypeDescriptor
where T : INotifyPropertyChanged
{
private readonly T _source;
private readonly ISynchronizeInvoke _syncObject;
public SynchronizedNotifyPropertyChanged(T source, ISynchronizeInvoke syncObject)
{
_source = source;
_syncObject = syncObject;
_source.PropertyChanged += (sender, args) => OnPropertyChanged(args.PropertyName);
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
if (PropertyChanged == null) return;
var handler = PropertyChanged;
_syncObject.BeginInvoke(handler, new object[] { this, new PropertyChangedEventArgs(propertyName) });
}
public T Source { get { return _source; }}
#region ICustomTypeDescriptor
public AttributeCollection GetAttributes()
{
return new AttributeCollection(null);
}
public string GetClassName()
{
return TypeDescriptor.GetClassName(typeof(T));
}
public string GetComponentName()
{
return TypeDescriptor.GetComponentName(typeof (T));
}
public TypeConverter GetConverter()
{
return TypeDescriptor.GetConverter(typeof (T));
}
public EventDescriptor GetDefaultEvent()
{
return TypeDescriptor.GetDefaultEvent(typeof (T));
}
public PropertyDescriptor GetDefaultProperty()
{
return TypeDescriptor.GetDefaultProperty(typeof(T));
}
public object GetEditor(Type editorBaseType)
{
return TypeDescriptor.GetEditor(typeof (T), editorBaseType);
}
public EventDescriptorCollection GetEvents()
{
return TypeDescriptor.GetEvents(typeof(T));
}
public EventDescriptorCollection GetEvents(Attribute[] attributes)
{
return TypeDescriptor.GetEvents(typeof (T), attributes);
}
public PropertyDescriptorCollection GetProperties()
{
return TypeDescriptor.GetProperties(typeof (T));
}
public PropertyDescriptorCollection GetProperties(Attribute[] attributes)
{
return TypeDescriptor.GetProperties(typeof(T), attributes);
}
public object GetPropertyOwner(PropertyDescriptor pd)
{
return _source;
}
#endregion ICustomTypeDescriptor
}
然後在用戶界面,我綁定到該包裝使用類似:
private void CreateBindings()
{
if (_model == null) return;
var threadSafeModel = new SynchronizedNotifyPropertyChanged<MyViewModel>(_model, this);
directiveLabel.DataBindings.Add("Text", threadSafeModel, "DirectiveText", false, DataSourceUpdateMode.OnPropertyChanged);
}
MyViewModel具有「DirectiveText」屬性,並沒有特別考慮到線程或視圖類實現INotifyPropertyChanged。
hmm ....所以我需要把它放在INotifyPropertyChanged事件?我已經用我的班級代碼更新了這個問題。 – TheGateKeeper 2012-04-14 20:29:56
我已更新澄清,無論是隻更改UI線程上的綁定對象,或綁定時將其包裝在助手類中。 – TheCodeKing 2012-04-14 20:48:49
沒有使用這個,但它標記爲答案,因爲它提供了很多細節。 – TheGateKeeper 2012-04-14 21:00:42