我正在使用C#和.NET Framework 4.6开发MVVM WPF应用程序。
我有这堂课:
public class ObservableObject : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChangedEvent(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
我在这里实现了INotifyPropertyChanged
,因为我不想在所有的ViewModel类中实现它。
要使用此类,我使用inherit:
public class Presenter : ObservableObject
{
private string _someText;
public string SomeText
{
get { return _someText; }
set
{
_someText = value;
RaisePropertyChangedEvent("SomeText");
}
}
}
但是,有没有办法使用ObservableObject
使用对象组合?
我理解对象组合而不是继承,在类ObservableObject
中创建Presenter
的私有对象实例。
我不确定是否有任何ViewModel类应该实现INotifyPropertyChanged
。
更新
这不是重复的问题。我问的是ViewModel是否总是要实现INotifyPropertyChanged
接口,或者我可以使用Object组合。我以前解释过。请仔细阅读我的问题。
答案 0 :(得分:0)
嗯,... ViewModels最好被视为Composition,但通知部分应该是Interface的实现(或者在你的case继承中)。您拥有DTO,ViewModel将是DTO的组合,具体取决于方案。
同样的东西的这种实现可能是乏味的,但对于WPF仍然是必要的。您可以采取哪些措施来简化流程,即使用像Fody这样的Veawrs。它会改变您对ViewModel的观察。 VM的所有属性都是默认的可观察属性,但是您可以排除那些您不想要的属性,或者您可以定义一个属性以让UI知道它还应该更新其他属性。
它使代码非常干净和简单。您不需要实现接口,但如果为类提供所需的属性,它将在构建时继承。
答案 1 :(得分:0)
如果您希望通过避免代码重复和在代码中使用字符串来提高健壮性。然后你可以使用以下基类。
我不知道合成的方法,但这个是我所知道的最好的方法。因为它有一些额外的好处(克隆变得容易a.s.o.)
public abstract class BindingBase : INotifyPropertyChanged
{
private IDictionary<string, object> _backingFields;
private IDictionary<string, object> BackingFields
{
get { return _backingFields ?? (_backingFields = new Dictionary<string, object>(); }
}
protected T GetValue<T>(Expression<Func<T>gt; expr)
{
var name = GetName(expr);
return BackingFields.Contains(name) ? (T)BackingFields[name].Value : default(T);
}
protected void SetValue<T>(Expression<Func<T>gt; expr, T value)
{
var name = GetName(expr);
if (BackingFields.Contains(name) && BackingFields[name].Value.Equals(value))
return; // return without doing anything, since the value is not changing
BackingFields[name] = value;
RaisePropertyChanged(name);
}
private void RaisePropertyChanged(string name)
{ // you know this part
}
private string GetName (Expression<Func<T> expr)
{ // implementation can be found via google
}
}
用法很简单。
public class BindingChild : BindingBase
{
public string SampleProperty
{
get { return GetValue(() => SampleProperty); }
set { SetValue(() => SampleProperty, value); }
}
}