Please, help me to understand one thing in the MVVM pattern:
For example, I need to display cities on a map.
In ViewModel I have ObservableCollection, that binded to a View ItemsSource.
ObservableCollection contains objects with type "City".
Must "City"-class be inherited from ObservableObject (I use MVVM Toolkit)? Or I should create a wrapper class, inherit it from ObservableObject, in ViewModel create new wrap-objects with data from "City"-objects and add them to the collection?
Thank you!
Assuming that your City class is in your model, and you actually need to know about changes to properties on the city object - then you should create a wrapper for it (i.e. CityViewModel). Your wrapper should listen to events that notify of any changes to the City class, and fire off the relevant Property Change notifications.
Model classes should be designed to fit with the model and should not change to suit your view - the point of having a ViewModel in the first place is to abstract your model from your view. The model should know nothing of the View.
If the properties of your City class dont change, or you dont care if they don change (and you are not a purist) then you could just expose it directly - without inheriting ObservableObject.
(Although I dont use MVVM toolkit, I cant see why in general you would need to inherit ObservableObject just because you are storing the City objects in an ObservableCollection).
The purist view however, is to wrap everything that you bind to and never expose anything from the model directly to the view.
ObservableCollection or ObservableObject has no relation with MVVM model. You can create a MVVM based application without ObservableCollection and ObservableObject (ObservableObject are used when you need to change the values of property of your class but if your application is readonly you dont even need it).
MVVM -
M-Model (business layer) , V-View (GUI), ViewModel- (Context of GUI).
When XAML works on binding. You must need a notification mechanism to notify GUI that something is changed. Now if a collection is changed means you added or removed an item from collection, you need to raise a notification which you dont need if you are working with ObservableCollection. Similarly, if your class City has a property Population which when changes need to notify GUI, that's why need to make an ObservableObject.
Hope it helps..
Related
I’m new to MVVM and am trying to establish good practices as I convert a large non-Model-View WinForms project. Here’s an example of a solution I’ve implemented. I’m wondering if there is a better pattern for solving this class of problem.
MyModel has ten properties. MyView exposes two of them for users to update. MyViewModel handles the usual stuff in between.
Other models depend on MyModel’s properties, so I only want to change MyModel when values are committed to. MyView has OK and Cancel buttons, so instead of having MyViewModel directly update MyModel when the user interacts with MyView, I’ve created another layer: MyTempModel. MyTempModel contains two properties which correspond to the two from MyModel.
So inside MyModel, prompting code looks something like this:
var tempModel = new TempModel{Prop1=Prop1,Prop2=Prop2};
bool? response = new MyView().ShowDialog();
if (response.HasValue && response.Value)
{
Prop1 = tempModel.Prop1
Prop2 = tempModel.Prop2
}
Thus if the user clicks ‘Cancel’, MyModel’s properties are not changed.
Note: Not shown here is that I set a reference to MyTempModel in MyViewModel once to establish that wiring. MyViewModel subscribes to property changed events in MyTempModel and MyView uses databinding to connect to MyViewModel.
model - > view data flow summary:
MyModel sets property in MyTempModel, which fires an event. MyViewModel’s evenhandler picks up the change and sets a dependency property, causing MyView to update.
view -> model data flow summary:
Changes to MyView result in dependency property in MyViewModel to change. This property’s setter pushes the value to MyTempModel. When user clicks Ok then MyModel copies values from MyTempModel.
I'm particularly interested in the role of the ViewModel. I have in mind that keeping dialogs "humble" is a good thing, and maybe that is spilling over into making ViewModels humble. So comments on what kind of functionality you put into your view models vs your domain models would be especially interesting.
I appreciate any and all design wisdom for this pattern. I'll gladly update this info if anyone needs clarification.
I don't think the use of a proxy class is a bad thing. I'm a little concerned about this: 'MyModel sets property in MyTempModel, which fires an event. MyViewModel’s evenhandler picks up the change and sets a dependency property, causing MyView to update.' I think that renders your Model classes a little less universal and obscures that functionality from the ViewModel. I would just use the ViewModel to mediate the swap in/out of the proxy, rather than having the Models do it. I also think that using a proxy opens up use of DataTemplates for that type which could make the UI work easier.
An alternative to the direction given by Alex is to make the viewmodel a representation of what is in both client and server side.
E.g., the number shown is always what the user entered and the background of the number indicates that this number has been confirmed or not (pending)by the server. The viewmodel could use two different properties to contain these values and a status property to indicate the fact the property has been synchronized.
This way the viewmodel captures all the user needs to know. All the view needs to do is bind to the correct properties for display and editing.
I have a model called Events and a Model called Persons. Am I fine, when I include an ObservableCollection of the type Persons in the Event Model? Is this right MVVM? Do I need everywhere an NotifyPropertyChanged?
Sounds fine to me. Have both your Event model and Person model implement INotifyPropertyChanged.
The front end can then be notified when the ObservableCollection changes and also be notified when properties on the Event and Person models change.
Will you display in the Events view the list of persons? if that is true then you are correct, that is MVVVM, remember the ViewModels stands between your Models and your Views, and need to satisfy the data and functional requirements of your View.
I'm new with MVVM and I'm stuck...
I have a ListBox in the MainWindow. The ListBox contains Items of type WhatEverViewModel which are displayed by DataTemplates. The user can interact with these items and the WhatEverViewModel has several DependencyProperties which may change during interaction.
The question I have is:
How can I elegantly react (in the MainWindowViewModel) to changes of DependencyProperties of the CURRENTLY SELECTED WhatEverViewModel. I personally would implement some events in the WhatEverViewModel and when the SelectedItem of the ListBox change, I would attach to the events of the currently selected WhatEverViewModel. But I think in MVVM there might be a more elegant way to solve this...
Thank you.
Make CurrentWhatEver a property of your MainWindowViewModel and bind the Listbox.SelectedItem property on it. This way, MainWindowViewModel knows when the selected WhatEver changes and can register/unregister to events it's interested in.
communication between viewmodel can be done in several ways.
Messenger/Mediator like the one form MVVM Light
Eventstuff like the one from PRISM
or simply use harcoupling and subscribe to the events from the WhatEverViewModel in your mainviewmodel.
btw why in hell to you use DependencyProperties in your Viewmodels? simple Properties with INotifyPropertyChanged are the way to go.
one more thing. why you want to react to changes in the SelectedViewmodel(or better what you want to achieve, with the selected viewmodel.)? if you just want to display some information in your view, simply bind the SelectedViewmodel to it. you should specify your question in that way.
EDIT
The WhatEverViewModel has a list which is also bound to a listbox (in
datatemplate) and depending on what I select in the WhatEverViewModel
I want to display some kind of "Configurator" in the MainViewModel. –
JensPfister1 1 hour ago
why not simply bind the SelectedWhatEverViewmodel.SelectedListEntryProperty to your configurator view? can you post some code?
You should implement the INotifyPropertyChanged interface on each of your ViewModels. Then when one of your properties changes call the PropertyChanged event, your views will get notifications that the property has changed (as long as your Binding is correct). If a property is a list or collection make sure that the list is based off an INotifyCollectionChanged.
Add a property for the Selected WhatEverViewModel to your MainWindowViewModel, bind that in your ListBox. Then in your MainWindowViewModel you can hook on to the property changes of your Selected WhatEverViewModel.
For more guidance read:
WPF MVVM INotifyPropertyChanged Implementation - Model or ViewModel
http://blogs.msdn.com/b/soultech/archive/2011/06/07/mvvm-tips-when-implementing-inotifypropertychanged.aspx
Let's say I've got a View. It's DataContext is bound to a ViewModel and the ViewModel exposes a Model property.
Is it MVVMlike to bind fields in the View to properties in the Model (e.g. Binding Path=Model.FirstName)?
Should the Model implement INotifyPropertyChanged?
My team are using Prism and MVVM in WPF. A lot of the Prism examples bind indirectly to the Model. I personally have my doubts that this is the correct approach. I think stuff in the model should expose behaviour (not just at the property level) and should communicate important events by, er, events - that clients can subscribe to or not.
I think that by having domain/model objects implement INotifyPropertyChanged somehow says to the world that it's UI/UX aware and kind of introduces some redundancy in the ViewModels.
What do you think? What works for you? A clear distinction between View/ViewModel/Model or a hybrid as used by the Prism examples?
I have seen many people implementing INotifyPropertyChanged directly in their Model and similarly I have seen people doing it in ViewModel as well.
I prefer and do this(implement INotifyPropertyChanged) in ViewModel. I agree with you it sometimes create redundancy in ViewModel but I prefer a clear distinction/separatation between ViewModel and Model and what their purpose should be. To me Model is just literally a Model. It is just representation of my Business Data nothing more nothing less. To me it should not cause any change in View (through notify property changed event). View should talk to ViewModel and ViewModel should use Model. I don't like View directly affecting the Model. I don't like using Model.FirstName because to me it seems like going against MMVM by telling View what is in Model
I have an ObservableCollection that's binded to a WPF ListView, and all the values appear correct. But how can I get a notification when something that has a 2-way binding changes?
Should I use INotifyPropertyChanged just like in Winforms? Or are there better practices to do these?
I saw some people suggesting using dependency properties online, but not sure if that's what should do.
If the class I want to add a property is a DependencyObject, I generally add a DependencyProperty. If the class is a POCO (plain old clr objects), then I implement INotifyPropertyChanged.
In generall, all my business objects are POCOs and therefore I use INotifyPropertyChanged. In the WPF world, I mostly use DependencyObjects (view models, custom controls, UserControls...) and therefore they are DependencyProperties. An exception are ViewModels representing items (to be used as items in an items source). In this case I think DependencyProperties are not very practical (Because Equals() and GetHashCode() of DependencyObjects are sealed and DependencyObject is thread-dependent).
If your class already is a DependencyObject, using DependencyProperties may give you some nice advantages: You don't have to back every value, a powerfull inheritance system, default-values, property changed callbacks per property, value coercion ... (I like DependencyProperties probably more than other people them like :)
Conclusion:
Based on the title of your question: How to get notified when something changes in a WPF window?, my way would be to add a DependencyProperty and not a clr-property because the Window is a DependencyObject. By the way, Visual Studio has a nice Snippet to create DependencyProperties.
There are really two scenarios:
1) Notifying the UI when a piece of data changes-either in the ViewModel or a Model that is bound to some UI elements (usually due to a data binding). In this scenario you'd use INotifyPropertyChanged.
Example: you have a Person object that binds it's Name to a TextBox. Person needs to implement INotifyPropertyChanged and the appropriate code needs to be attached to the Name Property's setter.
2) Creating custom UI elements where you'd want data to be bound. In this case, you'd use custom dependency properties.
Example: you have a custom UI element that spins when a certain condition is met. So you create an IsSpinning dependency property that you can bind to your ViewModel's IsLoading property. The custom control then uses the IsSpinning property to modify its behavior.
I hope that was clear...
You are right. You can use INotifyPropertyChanged or you can implement dependency properties. Personally I prefer INotifyPropertyChanged, it's more light and easyer to implement than dependency property.
I've generally used INotifyPropertyChanged for my data objects.
DependencyProperties can only be implemented on framework elements I believe.
Edit: I take that back... DependencyProperties can only be implemented on DependencyObjects (A FrameworkElement is an example of that as it derives from UIElement which derives from Visual which derives from DependencyObject).
If you have a UserControl, you may wish to implement a Dependency Property so you can Bind that Property (in XAML) to some other property. You could not do this scenario with INotifyPropertyChanged.