【发布时间】:2015-03-12 14:20:24
【问题描述】:
我发现键入和重新键入引发属性更改事件的相同属性 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 并手动输入所有支持字段和属性 getter 和 setter,只需:
public ObservableProperty<string> BindableText { get; private set; }
然后在构造函数中:
this.BindableText = new ObservableProperty<string>("Default Text");
视图现在将绑定到 XAML 中的 BindableText.Value。
所以每个属性都会有自己的 INotifyPropertyChanged 实现,自己成为一个迷你视图模型,创建这些实例的模型和视图模型根本不需要实现接口。
这很好用,可以绑定的属性很容易创建。 ViewModel 甚至可以引用模型上的可观察属性,例如:
public ObservableProperty<int> MyNumber { get { return MyModel.Number; } }
这样视图就不会直接绑定到模型上的属性,只能通过它们的视图模型间接绑定。
我的问题是,由于我没有很多经验,因此采用这种方法是否会出现任何潜在的软内存泄漏,我可以采取某种措施来应对? p>
【问题讨论】:
-
仅通过查看代码几乎不可能检测到内存泄漏,您需要分析您的应用程序才能真正查看它是否确实在泄漏内存。
-
有一种更好的方法可以避免
INotifyPropertyChanged中涉及表达式的拼写错误,例如stackoverflow.com/questions/2711435/… -
您可能希望使用参数属性
CallerMemberName让编译器为您插入属性名称。 -
ObservableProperty 类确实已经在其 INotifyPropertyChanged 的实现中使用了 CallerMemberName 属性。我在编写类之前就开始使用它,但是写出所有的属性 getter 和 setter 仍然很乏味。
-
米歇尔·德·奈斯,谢谢。你是对的。但是,我想知道是否有一种“防御性编程”方法来确保所有订阅者都取消订阅这些属性,这样就不会成为问题。
标签: c# mvvm memory-leaks inotifypropertychanged