Edw*_*uay 155 c# mvvm inotifypropertychanged
我经历过的大多数MVVM示例都使用了Model实现INotifyPropertyChanged,但在Josh Smith的CommandSink示例中 ,ViewModel实现了INotifyPropertyChanged.
我还在认知上把MVVM概念放在一起,所以我不知道是否:
您曾参与MVVM项目的其他经历是什么?
小智 137
我强烈反对模型不应该实现的概念INotifyPropertyChanged
.此界面不是特定于UI的!它只是告知变化.实际上,WPF大量使用它来识别变化,但这并不意味着它是一个UI界面.我会将它与下面的评论进行比较:" 轮胎是汽车配件 ".当然可以,但自行车,公共汽车等也使用它.总之,不要将该接口作为UI事物.
话虽如此,但这并不一定意味着我相信模型应该提供通知.实际上,根据经验,除非有必要,否则模型不应实现此接口.在大多数情况下,没有服务器数据被推送到客户端应用程序,模型可能是陈旧的.但如果听取金融市场数据,那么我不明白为什么模型无法实现界面.例如,如果我有非UI逻辑(例如服务),当它收到给定值的买价或卖价时会发出警报(例如通过电子邮件)或下订单,该怎么办?这可能是一个可能的清洁解决方案.
但是,有不同的实现方式,但我总是赞成简单并避免冗余.
什么是更好的?在视图模型上定义集合或属性上的事件更改并将其传播到模型或让视图本质上更新模型(通过视图模型)?
每当你看到有人声称" 你不能做到这一点或那样 " 时,底线就是他们不知道他们在说什么的标志.
这实际上取决于你的情况,事实上MVVM是一个有很多问题的框架,我还没有看到一个全面的MVVM实现.
我希望我有更多的时间来解释MVVM的各种风格以及常见问题的一些解决方案 - 主要由其他开发人员提供,但我想我将不得不再做一次.
Ste*_*ins 101
我说的恰恰相反,我总是把我INotifyPropertyChanged
放在我的ViewModel上 - 你真的不想用一个相当WPF特定的功能来污染你的模型,比如INotifyPropertyChanged
那些东西应该放在ViewModel中.
我相信别人会不同意,但这就是我工作的方式.
Son*_*Ali 28
在MV-VM中,ViewModel始终(Model并不总是)实现INotifyPropertyChanged
查看来自http://blogs.msdn.com/llobo/archive/2009/05/01/download-mv-vm-project-template-toolkit.aspx的MV-VM项目模板/工具包.它使用DelegateCommand
for命令,它应该是你MV-VM项目的一个很好的起始模板.
Rhy*_*ous 12
我认为MVVM命名很差,并且调用ViewModel是一个ViewModel会导致许多人错过精心设计的架构的一个重要特性,这是一个控制数据的DataController,无论是谁试图触摸它.
如果您将View-Model视为更多的DataController并实现一个架构,其中DataController是唯一触及数据的项目,那么您永远不会直接触摸数据,但始终使用DataController.DataController对UI很有用,但不一定只对UI有用.它适用于业务层,UI层等...
DataModel -------- DataController ------ View
/
Business --------/
Run Code Online (Sandbox Code Playgroud)
你最终得到了这样的模型.甚至企业也应该只使用ViewModel触摸数据.然后你的难题就消失了.
这取决于您如何实施模型.我的公司使用类似于Lhotka的CSLA对象的业务对象,并在整个业务模型中广泛使用INotifyPropertyChanged.
我们的验证引擎在很大程度上依赖于通过此机制通知属性发生变化,并且它非常有效.显然,如果您使用的是业务对象以外的其他实现,其中更改通知对操作不是那么重要,那么您可能还有其他方法可以检测业务模型中的更改.
我们还有视图模型,可以根据需要传播模型中的更改,但视图模型本身正在监听基础模型更改.
我同意 Paulo 的回答,INotifyPropertyChanged
在 Models 中实施是完全可以接受的,微软甚至建议 -
通常,模型实现了易于绑定到视图的工具。这通常意味着它通过
INotifyPropertyChanged
和INotifyCollectionChanged
接口支持属性和集合更改通知。表示对象集合的模型类通常派生自ObservableCollection<T>
提供INotifyCollectionChanged
接口实现的 类 。
虽然由您决定是否需要这种类型的实现,但请记住 -
如果您的模型类没有实现所需的接口怎么办?
有时候,你需要与不执行模型对象的工作
INotifyPropertyChanged
,INotifyCollectionChanged
,IDataErrorInfo
,或INotifyDataErrorInfo
接口。在这些情况下,视图模型可能需要包装模型对象并向视图公开所需的属性。这些属性的值将由模型对象直接提供。视图模型将为它公开的属性实现所需的接口,以便视图可以轻松地将数据绑定到它们。
取自 - http://msdn.microsoft.com/en-us/library/gg405484(PandP.40).aspx
我曾参与过一些我们没有INotifyPropertyChanged
在模型中实现的项目,因此我们遇到了很多问题;VM 中需要不必要的属性重复,同时我们必须在将它们传递给 BL/DL 之前更新底层对象(具有更新的值)。
如果您需要处理模型对象的集合(例如在可编辑的网格或列表中)或复杂模型,您将面临特别的问题;模型对象不会自动更新,您必须在 VM 中管理所有这些。
我认为这一切都取决于用例。
当您有一个带有大量属性的简单模型时,您可以让它实现 INPC。简单地说,我的意思是这个模型看起来很像POCO。
如果您的模型更复杂并且存在于交互式模型域中 - 模型引用模型、订阅其他模型的事件 - 将模型事件实现为 INPC 是一场噩梦。
将您自己置于某个必须与其他模型协作的模型实体的位置。您有各种活动可供订阅。它们全部作为 INPC 实现。想象一下您拥有的那些事件处理程序。一串巨大的 if 子句和/或 switch 子句。
INPC 的另一个问题。您应该将应用程序设计为依赖于抽象,而不是实现。这通常是使用接口来完成的。
让我们看一下同一抽象的两种不同实现:
public class ConnectionStateChangedEventArgs : EventArgs
{
public bool IsConnected {get;set;}
}
interface IConnectionManagerINPC : INotifyPropertyChanged
{
string Name {get;}
int ConnectionsLimit {get;}
/*
A few more properties
*/
bool IsConnected {get;}
}
interface IConnectionManager
{
string Name {get;}
int ConnectionsLimit {get;}
/*
A few more properties
*/
event EventHandler<ConnectionStateChangedEventArgs> ConnectionStateChanged;
bool IsConnected {get;}
}
Run Code Online (Sandbox Code Playgroud)
现在看看他们两个。IConnectionManagerINPC 告诉您什么?它的一些属性可能会改变。你不知道他们中的哪一个。事实上,设计中只有 IsConnected 发生变化,因为其余部分都是只读的。
相反,IConnectionManager 的意图很明确:“我可以告诉你,我的 IsConnected 属性的值可能会改变”。