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
Related
I'm currently in the need of setting the SelectedIndex property of my TabControl when a certain event (IEventAggregator) takes place and thought about how I'd implement that.
I came up with 2 possibilities:
Use GetView() provided by ViewAware in order to access my TabControl and set the SelectedIndex to my value
Use a property in my associated ViewModel and bind this property to my TabControl's SelectedIndex property via XAML
Both options are working fine but I personally want to get this question answered since this is not the first time I'm wondering where to implement the functionality in such cases.
I know that the first option won't enable the Notify support but besides that: What would be the proper way?
Having a GetView() method to manipulate the view directly from the viewmodel completely breaks MVVM. You might as well just put all your logic in codebehind. The whole point of MVVM is to abstract away the actual view so that it is decoupled from the logic, and the app can be unit tested.
What if you change your mind about the tabs in the future and decide to show your multiple views some other way? You've now got to start editing your viewmodel to edit the new view instead of just tweaking some XAML.
And for unit testing you're going to have no way to mock out your TabControl.
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..
Is there anyway to force XAML to completely redraw all of its elements and thereby have all of the data being displayed updated? This is within a MVVM architecture.
In a MVVM architecture, the View-Model implements INotifyPropertyChanged interface and its properties fire the PropertyChanged event. When this event is fired, the View (which is bound to the View-Model using XAML Binding System) receives a notification about the changes in the value of the properties in the View-Model and it refreshes, showing the updated data on screen.
Therefore, if you are using the MVVM architecture, the only thing you need to do in order to reflect changes in the view is updating the properties in your View-Model.
If you have any specific situation in which the binding system is not giving you the desired results, can you please explain in more detail so that it is possible to address your problem better?
I have a scenario where I have user controls on TabItem of a TabControl in the view. These user controls are individually bound to separate objects in the ViewModel. What I need is these controls to pass through to their bound object, the IsSelected property value of the parent TabItem.
Any ideas on how to do this kind of relay binding?
Why not have your ParentViewModel track the SelectedIndex of the TabControl, instead of tracking individual IsSelected values?
If that doesn't work, usually I use something like Microsoft PRISM's EventAggregator or MVVM Light's Messenger to broadcast messages to other interested ViewModels.
In this example, I would still bind the SelectedIndex to something in the ParentViewModel, and anytime that changes I would broadcast a SelectedTabChanged message. The individual child ViewModels that are interested in such information would subscribe to these messages, and perform whatever logic was needed based on if the selected tab is the one they belong to.
What is the fastest way to update my DataContext binding to my WPF usercontrol so that it shows changes in the object it is bound to in the view?
The best option is to make your DataContext object implement INotifyPropertyChanged. Make any collections implement INotifyCollectionChanged (ie: use an ObservableCollection<T> instead of List<T>, etc).
If you do this, then the bindings will automatically stay up to date, with no effort on your part.
Binding an ObservableCollection (which implements a specific interface) with objects that implement INotifyPropertyChanged will immediately show changes to their values in the front end or backend whenever you make changes, as long as the binding modes are set to two way binding.
This question here appears to be very similar.
Silverlight: How to force binding after setting the DataContext property
If you don't want to implement the INotifyProperty, you can use my answer and just set the datacontext again