我已经重构了我的WPF应用程序,以便DataContexts不再是某个实现INotifyPropertyChanged
的类的实例,而是我的一些自定义接口。实现每个自定义接口的对象也必须实现INotifyPropertyChanged
。但是我不能再在构建时强制执行此要求。我不确定这是否是个好主意。
例如,考虑以下简单的类层次结构
// Base view model class has stock implementation of INotifyPropertyChanged.
public BaseViewModel : INotifyPropertyChanged
{
// Assume INotifyPropertyChanged implementation with this utility to raise the event
void RaisePropertyChanged(string property) { // ...blah blah blah ... }
}
// Interface for nameable object
public interface INameable
{
string Name { get; set; }
}
// View model for nameable object
public class NameableViewModel : BaseViewModel, INameable
{
private string _name;
public string Name
{
get => _name;
set
{
if (value == _name) return;
_name = value
RaisePropertyChanged();
}
}
// Main view model exposes named object by interface, NOT by view-model
public class MainViewModel : BaseViewModel
{
public INameable NameableObject { get; set; }
}
以下是绑定到INameable
而不是NameableViewModel
的视图
<UserControl x:Class="MyView"
(... blah blah blah... namespace declarations...)
d:DataContext="{d:DesignInstance MainViewModel}">
<TextBox DataContext={Binding NameableObject.Name, Mode=TwoWay}"/>
</UserControl>
这在WPF中很好用,因为它查询INotifyPropertyChanged
的任何数据上下文。即使收到的只是INameable
,它也会收到PropertyChanged通知。但是,如果我忘记正确设置类,则WPF只会默默地永远不会收到属性更改通知。我可能最终会花一些时间注意到或跟踪错误(此处的测试资源有限)。
此外,在我的后台代码中,有时我使用Josh Smith出色的INotifyPropertyChanged
通过PropertyObserver
手动监视某些对象。
public class PropertyObserver<TPropertySource>
: IWeakEventListener
where TPropertySource : INotifyPropertyChanged
{
... blah blah blah..
}
此 确实 在构建时需要INotifyPropertyChanged,这在我使用BaseViewModel实例时非常有用。但是现在我只有一个接口,我必须自己查询它,并依靠运行时错误让我知道自己搞砸了。
这使我想到了我的问题。一位将军和一位非常具体的人:
NotSupportedException
?还有吗?答案 0 :(得分:1)
我不确定您指的是什么“设计”或“实践”。我没有看到一般的模式,只是看到了接口的特定用途,对此我的目的尚不清楚。
以我的经验,最好使视图模型尽可能简单。在某些情况下,他们甚至不需要实现INotifyPropertyChanged
(以只读视图模型为例)。通常,我使用提供ViewModelBase
的MVVM框架(例如MVVM Light Toolkit)。我制作的几乎所有视图模型都源自ViewModelBase
,并且该视图模型仅包含setter,getter和command。
对于第二个问题,我认为具体的例外情况取决于使用接口的意图。但也许是一个普遍的例外情况,可能是InvalidOperationException
。