我发现键入和重新键入引发属性更改事件的相同属性 getter 和 setter 是乏味的,并且可能容易出错,因为属性名称是作为类型字符串传递的。在寻找更简单的方法之后,我创建了以下泛型类:
public class ObservableProperty<T> : INotifyPropertyChanged
{
private T _backingField;
public T Value
{
get { return this._backingField; }
set
{
if (!EqualityComparer<T>.Default.Equals(this._backingField, value))
{
this._backingField = value;
this.TriggerPropertyChangedEvent();
}
}
}
/// <summary>
/// Creates an observable property with a default initial value.
/// </summary>
public ObservableProperty() : this(default(T)) { }
/// <summary>
/// Creates an observable property with the specified initial value.
/// </summary>
/// <param name="initialValue">The value to initialize the observable property to.</param>
public ObservableProperty(T initialValue)
{
this.Value = initialValue;
}
#region INotifyPropertyChanged Implementation
public event PropertyChangedEventHandler PropertyChanged;
protected void TriggerPropertyChangedEvent([CallerMemberName]string propertyName = null)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion // INotifyPropertyChanged Implementation
}
现在,无需在整个 ViewModel 上实现 INotifyPropertyChanged 并手动键入所有支持字段、属性获取器和 setter,而只需做的是:
public ObservableProperty<string> BindableText { get; private set; }
然后在构造函数中:
this.BindableText = new ObservableProperty<string>("Default Text");
视图现在将绑定到 XAML 中的 BindableText.Value。
因此,每个属性都有自己的 INotifyPropertyChanged 实现,成为自己的迷你视图模型,并且创建这些实例的模型和视图模型根本不需要实现该接口。
这工作正常,可以绑定到的属性非常容易创建。ViewModels甚至可以引用模型上的可观察属性,例如:
public ObservableProperty<int> MyNumber { get { return MyModel.Number; } }
这样视图就不会直接绑定到模型上的属性,而只能通过其视图模型间接绑定。
我的问题是,由于这不是我有很多经验的东西,因此采取这种方法是否会有任何潜在的软内存泄漏,我可以以某种方式采取措施?
采取这种方法是否会有任何潜在的软内存泄漏,我可以以某种方式采取措施?
获得内存泄漏的风险与标准INotifyPropertyChange
方法相同:
-
如果这些
ObservableProperties
用于XAML
中的绑定,则不会泄漏内存,因为WPF
使用Weak Events
来实现INotifyPropertyChange
接口的对象的绑定属性。 -
如果在代码中使用这些
ObservableProperties
来订阅INotifyPropertyChange
事件,则可能是内存泄漏。
例如,如果ViewModel
订阅INotifyPropertyChange
Model
的此类ObservableProperty
对象的事件,则在垃圾回收或取消订阅之前Model
不会ViewModel
ViewModel
进行垃圾回收。如果为一个Model
创建了许多ViewModels
,则此泄漏可能会很明显。