C# 在 MVVM 中,ViewModel 或 Model 是否应该实现 INotifyPropertyChanged?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/772214/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
In MVVM should the ViewModel or Model implement INotifyPropertyChanged?
提问by Edward Tanguay
Most MVVM examples I have worked through have had the Modelimplement INotifyPropertyChanged
, but in Josh Smith's CommandSink examplethe ViewModel implements INotifyPropertyChanged
.
我处理过的大多数 MVVM 示例都有Model实现 INotifyPropertyChanged
,但在Josh Smith 的 CommandSink 示例中, ViewModel 实现了INotifyPropertyChanged
。
I'm still cognitively putting together the MVVM concepts, so I don't know if:
我仍然在认知上把 MVVM 概念放在一起,所以我不知道:
- You have to put the
INotifyPropertyChanged
in the ViewModel to getCommandSink
to work - This is just an aberration of the norm and it doesn't really matter
- You should always have the Model implement
INotifyPropertyChanged
and this is just a mistake which would be corrected if this were developed from a code example to an application
- 您必须将 放入
INotifyPropertyChanged
ViewModel 才能开始CommandSink
工作 - 这只是一种反常现象,并不重要
- 您应该始终拥有模型实现
INotifyPropertyChanged
,这只是一个错误,如果将其从代码示例开发为应用程序,则会得到纠正
What have been others' experiences on MVVM projects you have worked on?
其他人在您参与的 MVVM 项目中有何经验?
采纳答案by Steven Robbins
I'd say quite the opposite, I always put my INotifyPropertyChanged
on my ViewModel - you really don't want to be polluting your model with a fairly WPF specific feature like INotifyPropertyChanged
, that stuff should sit in the ViewModel.
我会说恰恰相反,我总是把我的INotifyPropertyChanged
观点放在我的 ViewModel 上——你真的不想用一个相当 WPF 特定的功能来污染你的模型,比如INotifyPropertyChanged
,那些东西应该放在 ViewModel 中。
I'm sure others would disagree, but that's the way I work.
我相信其他人会不同意,但这就是我的工作方式。
回答by Steve Dunn
I'd say in your ViewModel. It's not part of the Model as the Model is UI agnostic. The Model should be 'everything EXCEPT business agnostic'
我会在你的 ViewModel 中说。它不是模型的一部分,因为模型与 UI 无关。模型应该是“除了业务不可知的一切”
回答by Steve Mitcham
It depends on how you've implemented your model. My company uses business objects similar to Lhotka's CSLA objects and make extensive use of INotifyPropertyChanged
throughout the business model.
这取决于您如何实现模型。我公司使用类似于 Lhotka 的 CSLA 对象INotifyPropertyChanged
的业务对象,并在整个业务模型中广泛使用。
Our validation engine relies heavily on being notified that properties change through this mechanism and it works very well. Obviously, if you are using a different implementation other than business objects where notification of changes isn't as critical to the operation, you may have other methods for detecting change in your business model.
我们的验证引擎在很大程度上依赖于通过这种机制获得属性更改的通知,并且它运行良好。显然,如果您使用的是业务对象以外的其他实现,其中更改通知对操作不是那么重要,那么您可能有其他方法来检测业务模型中的更改。
We also have View Models that propagate the changes from the Model where needed, but the View Models themselves are listening to the underlying Model changes.
我们也有视图模型在需要时从模型传播更改,但视图模型本身正在侦听底层模型更改。
回答by Soni Ali
In M-V-VM the ViewModel always (Model not always) implements INotifyPropertyChanged
在 MV-VM 中,ViewModel 总是(Model not always)实现 INotifyPropertyChanged
Check out the M-V-VM Project Template/Toolkit from http://blogs.msdn.com/llobo/archive/2009/05/01/download-m-v-vm-project-template-toolkit.aspx.
It uses the DelegateCommand
for commanding and it should be a great starting template for you M-V-VM projects.
从http://blogs.msdn.com/llobo/archive/2009/05/01/download-mv-vm-project-template-toolkit.aspx查看 MV-VM 项目模板/工具包。它使用DelegateCommand
for 命令,它应该是您 MV-VM 项目的一个很好的起始模板。
回答by Andrey Khataev
回答by Paulo Sousa
I strongly disagree with the concept that the Model should not implement the INotifyPropertyChanged
. This interface is not UI specific! It simply informs of a change. Indeed, WPF heavily uses this to identify changes, but that doesn't mean it is an UI interface.
I would compare it to the following comment: "A tire is a car accessory". Sure it is, but bikes, buses, etc. also use it. In summary, do not take that interface as an UI thing.
我强烈不同意模型不应实现INotifyPropertyChanged
. 此界面不是特定于 UI 的!它只是通知更改。事实上,WPF 大量使用它来识别更改,但这并不意味着它是一个 UI 界面。我会将其与以下评论进行比较:“轮胎是汽车配件”。当然可以,但自行车、公共汽车等也使用它。总之,不要把那个界面当成 UI 的东西。
Having said that, it doesn't necessarily mean I believe that the Model should be providing notifications. In fact, as a rule of thumb, the model should not implement this interface, unless it is necessary.In most cases where no server data is pushed to the client app, the model can be stale. But if listening to financial market data, then I do not see why the model cannot implement the interface. As an example, what if I have non-UI logic such as a service that when it receives a Bid or Ask price for a given value it issues an alert (ex. through an email) or places an order? This could be a possible clean solution.
话虽如此,这并不一定意味着我认为模型应该提供通知。事实上,根据经验,模型不应该实现这个接口,除非有必要。在没有将服务器数据推送到客户端应用程序的大多数情况下,模型可能已经过时。但是如果听金融市场数据,那么我不明白为什么模型不能实现接口。举个例子,如果我有一个非 UI 逻辑,比如一个服务,当它收到一个给定值的买价或卖价时,它会发出警报(例如通过电子邮件)或下订单?这可能是一个可能的清洁解决方案。
However, there are different ways of achieving things, but I would always argue in favor of simplicity and avoid redundancy.
然而,实现事物的方法有很多种,但我总是主张简单并避免冗余。
What is better? Defining events on a collection or property changes on the view model and propagating it to the model or having the view intrinsically update the model (through the view model)?
什么是更好的?定义集合上的事件或视图模型上的属性更改并将其传播到模型或让视图本质上更新模型(通过视图模型)?
The bottom line whenever you see someone claiming that "you can't do this or that" it is a sign they do not know what they are talking about.
底线每当你看到有人声称“你不能做这个或那个”时,这表明他们不知道他们在说什么。
It really depends on your case and in fact MVVM is a framework with lots of issues and I am yet to see a common implementation of MVVM across the board.
这真的取决于你的情况,事实上 MVVM 是一个有很多问题的框架,我还没有看到全面的 MVVM 实现。
I wish I had more time to explain the many flavors of MVVM and some solutions to common problems - mostly provided by other developers, but I guess I will have to do it another time.
我希望我有更多的时间来解释 MVVM 的多种风格和一些常见问题的解决方案 - 主要由其他开发人员提供,但我想我将不得不再做一次。
回答by Rhyous
I think MVVM is very poorly named and calling the ViewModel a ViewModel causes many to miss an important feature of a well-designed architecture, which is a DataController that controls the data no matter who is trying to touch it.
我认为 MVVM 的命名非常糟糕,将 ViewModel 称为 ViewModel 导致许多人错过了精心设计的架构的一个重要功能,即无论谁试图触摸数据,它都可以控制数据的 DataController。
If you think of the View-Model as more of a DataController and implement an architecture where your DataController is the only item that touches the data, then you would never touch the data directly, but always use the DataController. The DataController is useful to the UI but not necessarily only for the UI. It is for business layer, UI layer, etc...
如果您认为 View-Model 更像是一个 DataController 并实现一个架构,其中您的 DataController 是唯一接触数据的项目,那么您将永远不会直接接触数据,而是始终使用 DataController。DataController 对 UI 很有用,但不一定只对 UI 有用。它用于业务层,UI层等...
DataModel -------- DataController ------ View
/
Business --------/
You end up with a model like this. Even the business should only touch the data using the ViewModel. Then your conundrum just goes away.
你最终会得到一个这样的模型。即使是业务也应该只使用 ViewModel 接触数据。然后你的难题就消失了。
回答by Syed
Normally ViewModel will implement the INotifyPropertyChanged
. Model can be anything(xml file, database or even object). Model is used to give the data to the viewmodel, which propagates to the view.
通常 ViewModel 将实现INotifyPropertyChanged
. 模型可以是任何东西(xml 文件、数据库甚至对象)。模型用于将数据提供给视图模型,视图模型传播到视图。
回答by Dummy01
Suppose that the reference of the object in your view changes. How you will notify all properties to be updated in order to show the correct values? Calling OnPropertyChanged
in your view for all object's properties is rubbish to my point of view.
假设视图中对象的引用发生了变化。您将如何通知所有要更新的属性以显示正确的值?OnPropertyChanged
在我看来,在您的视图中调用所有对象的属性是垃圾。
So what I do is to let the object itself to notify anyone when a value in a property changes, and in my view I use bindings like Object.Property1
, Object.Property2
and on. In that way if I just want to change the object that is currently maintained in my view I just do OnPropertyChanged("Object")
.
所以我要做的是让对象本身在属性中的值发生变化时通知任何人,在我看来,我使用诸如Object.Property1
,Object.Property2
等等之类的绑定。这样,如果我只想更改当前在我的视图中维护的对象,我就这样做OnPropertyChanged("Object")
。
To avoid hundreds of notifications during the loading of objects, I have a private boolean indicator that I set it to true during loading which is checked from the object's OnPropertyChanged
and does nothing.
为了避免在加载对象期间收到数百个通知,我有一个私有的布尔指示器,我在加载期间将其设置为 true,该指示器从对象的检查中进行检查OnPropertyChanged
并且不执行任何操作。
回答by Anand Kumar
I am using the INotifyPropertyChange
interface in a model. Actually, a model property change should be fired by the UI or external client only.
我INotifyPropertyChange
在模型中使用接口。实际上,模型属性更改只能由 UI 或外部客户端触发。
I've noticed several advantages and disadvantages:
我注意到了几个优点和缺点:
Advantages
好处
Notifier is in the business model
通知者在商业模式中
- As per domain driven, it is right. It should decide when to raise and when not to.
- 根据域驱动,这是正确的。它应该决定何时加注,何时不加注。
Disadvantages
缺点
The model has properties (qty, rate, commission, totalfrieght). Totalfrieght is calculated using qty, rate, commission change.
该模型具有属性(数量、费率、佣金、总运费)。总运费是使用数量、费率、佣金变化来计算的。
On loading values from db, total frieght calculation is called 3 times (qty, rate, commission). It should be once.
If rate, qty is assigned in the business layer, again notifier is called.
There should be an option to disable this, possibly in the base class. However, developers could forgot to do this.
从 db 加载值时,总运费计算被调用 3 次(数量、费率、佣金)。应该是一次。
如果在业务层分配了 rate、qty,则再次调用通知程序。
应该有一个选项可以禁用它,可能在基类中。但是,开发人员可能会忘记这样做。