I guess I am still a little hazy on how communication goes in MVVM. I read that you are not supposed to use events to communicate with the viewmodel, so i assume that you send a command.
However, commands actually bubble up within the visual tree (the view), right? so then it may reach some target control that can handle the command. Does that target control then have a viewmodel that can modify the model?
Sorry, I'm really confused about how to get commands from the view to the model. I assume that getting information the other way is just a simple matter of having the model implement Inotifypropertychanged to tell the viewmodel that it has changed and then have the viewmodel implement inotifypropertychanged so that the view can bind to the viewmodel and have the properties update.
http://blogs.msdn.com/blogfiles/erwinvandervalk/WindowsLiveWriter/ImplementingtheModelViewViewModelpattern_D996/image_14.png
Not all commands bubble - those are RoutedUICommands, which are just a particular implementation of the ICommand interface provided by the framework. You can implement your own ICommand objects that have custom behavior and act just like normal objects (no bubbling, tunneling). If you create them in your ViewModel, certain View objects like Buttons and MenuItems can bind directly to them through their 'Command' properties.
Related
I have read a lot about MVVM in the past, but I am not completely getting there.
I looked at MVVM Light framework and understood the pattern of the ServiceLocater to bind View and Viewmodel. But I didnt find anything helpful about the connection between the model and the viewmodel.
So far I know that the Viewmodel should have a private "Model" instance and some public properties to be read by the View. The Model should implement the INotifyPropertyChanged event to notify the Viewmodel, which can do something with the data and/or change its public properties and notify the view.
I hope I got it right so far. But: Where is the Model created? and how does the Viewmodel gets the Model? Does the Viewmodel creates it?
My Application gets data via bluetooth continously and process them in the background. At different process-stages it changes different Models. My first approach was a Singleton which holds all Models. The Viewmodel gets the Model from the Singleton and the Background-process can access the Model too. But I think that "pattern" is really bad.., but i cannot find any solution to do this "nice". I dont know how to share the model between the viewmodel and the background-process (businessLogic) properly.
I am glad about any help :)
As far as I know and use to do in our WPF projects - classical MVVM delegates Model creation on ViewModel. ViewModel should be Model-aware. Sometimes ViewModel could rely on ServiceLocator or DependencyInjection patterns to find out and create Model class (ie by interface).
I have multiple of views (user controls), each with its own ViewModel. To navigate between them I am using buttons. Buttons display image and text from corresponding view model and also need column and row (because there are like 10 views: 10 columns with different number of rows each).
Right now buttons are created dynamically (I made a Navigator control for this) and for view models I have base class to hold text, image, column and row. Number of views available will be different (depends on user level and certain settings), that's why it's I need control here.
Question: how shall my control get data from view models?
Right now I have interface INavigator, defined in (lol) control itself. And view models implement it. I could go opposite, let my control to know about view models. Both looks wrong.
There is a single Navigator control what has, lets say, Items bound to a list of view models. It can cast each view model to INavigator or ViewModelBase (common for all pages) to obtain specific view model image, text, column and row. So either view model knows about control (to implement INavigator) or control knows about ViewModelBase.. And this is a problem, both solution bind tight control and view models, which is bad in mvvm.
Schematically
The way you've drawn your diagram answers your own question as to how you should structure the code for this.
What you need is one VM (let's call it MainVM) which contains an ObservableCollection<VMBase> of the other VMs (using your base type so that they can all happily live in the same collection).
Your View needs an ItemsControl (bound to your ObservableCollection<VMBase>) where you specify a DataTemplate for the Button using the properties exposed by the VMBase type only. Set the Command property in the Button to call SwitchCommand, CommandParameter is set to the item itself (i.e. {Binding .}).
Your View also needs a ContentControl bound to a SelectedVM property on MainVM which you can populate.
Implement SwitchCommand to set the SelectedVM property based on the value from the CommandParameter.
public void ExecuteSwitchCommand(object parameter)
{
var vmBase = parameter as VMBase;
if (vmBase != null)
SelectedVM = vmBase;
}
All properties mentioned here should be INotifyPropertyChanged enabled so that the View registers when they change and updates the UI.
To get the different UIs for the ContentControl, add type-specific DataTemplates for each of your specific VM types to the Resources file of your View (or if you're smart and are building a custom plug-in framework, merge the Resource Dictionaries).
A lot of people forget with MVVM that the whole point is that there is a purposeful separation of View from ViewModel, thus meaning you can potentially have many Views for a single ViewModel, which is what this demonstrates.
I find it's easiest to think of MVVM as a top-down approach... View knows about it's ViewModel, ViewModel knows about its Model, but Model does not know about its ViewModel and ViewModel does not know about its View.
I also find a View-first approach to development the easiest to work with, as UI development in XAML is static (has to be).
I think a lot of people get to wrapped up in 'making every component (M, V, VM) standalone and replaceable', myself included, but I've slowly come to the conclusion that is just counter-productive.
Technically, sure you could get very complicated and using IoC containers, create some ViewLocator object which binds a View-type to a ViewModel-type, but... what exactly does that gain you besides more confusion? It makes it honestly harder (because I've done this at one point) to develop because now you've lost design-time support first and foremost, among other things; and you're still either binding to a specific view model interface in your view or creating the binding at run-time. Why complicate it?
This article is a good read, and the first Note: explicitly talks about View vs. ViewModel. Hopefully, it will help you draw your own conclusions.
To directly answer your question, I think having your ViewModels implement an INavigator interface of some sort is probably ideal. Remember your VM is 'glue' between your view and model/business logic, its job is to transform business data into data that is consumable by your views, so it exists somewhere between both your UI and business layers.
This is why there are things like Messengers and View Services, which is where your navigator service on the ViewModels can fit in nicely.
I think the design has led to a no way out situation.
I believe that creating a custom button control where the dependency properties tie the image, the row and column actually provide a way for the page, which it resides on ,to get that information to them; whether they are dynamically created or not.
Continuing on with that thought. There is no MVVM logic applied to a custom control, the control contains what it needs to do its job and that is through the dependency properties as mentioned. Any functionality of the button should be done by commanding; all this makes the button data driven and robust enough to use in a MVVM methodology or not.
Question: how shall my control get data from view models?
There should only one viewmodel which is the page the control resides on. The control is simply bound to information which ultimately resides on that VM. How it gets there, that is up to the programmer. If the button is going to contain state data, that is bound from its dependency property in a two way fashion back to the item it is bound to.
By keeping VMs out of the buttons and only having one VM that is the best way to segregate and maintain the data. Unless I am really missing something here....
Same as others here I find it a bit hard to actually understand what you are asking, so this is quite general. The answer to the question header is simply: the Control gets the data from the ViewModel through bindings, always. You set the DataContext of your Control to the corresponding ViewModel, and from there you keep the ViewModel and the Control synchronized:
If you add an ItemsControl containing buttons to the View, you add an ObservableCollection<ButtonViewModel> to the ViewModel and bind the ItemsSource of the ItemsControl to this.
If you allow the user to dynamically add content to the View, the actual code that does it resides in the ViewModel, e.g. when the user clicks on a button "Add Button", you use the Command property to call a ViewModel method that adds a ButtonViewModel to the collection and the View will automatically reflect your changes.
There do exist complicated cases that are impossible to code exclusively in the ViewModel, I have found Behaviors to be the missing link there, but I'll get into that when you show me the specific case.
If you'd like to get a working example, please provide as much code as you can, with your exact expectations of what it should do.
I have a CustomControl B, which uses a DataContext/MVVM (viewModelB). Now I want to bind one Property of my CustomControl to another control A (uses viewModelA as DataContext).
So I have two Ideas:
Whenever PropA in viewModelA changes, I could directly update PropB in the viewModelB. But this creates a dependency between the viewModels, which seems ugly to me. Or is this a common way in the MVVM pattern and can't be avoided?
As an alternative I could think of a dependency property on CustomControlB and wire it to CustomControlA's viewModel by a binding, something like that:
<myControlB PropB={Binding ElementName=myControlA, Path=DataContext.PropA} />.
So far so good, but the dependency property is defined on the view now. How should I visualize it?
a) Should I transfer the value (from the property wrapper) to viewModelB and bind to it from viewB's XAML code?
b) Or should I directly update the view from B's codeBehind? Would this be still a proper MVVM "style"?
Which of the options would you recommend?
regards
Andreas
As long as ViewModelA doesn't actively update ViewModelB, there is no real coupling between the two viewmodels. What I mean is that if your main view model (which knows both viewmodels) is the one that wires up the binding, the view models are still loosely coupled.
So to me any of these are fine:
Bind directly to myControlA.DataContext.PropA from XAML
Have the MainViewModel register for ViewModelA's property changed event and modify ViewModelB's property as necessary. Here MainViewModel knows about the two view models, but they know nothing of each other.
Should I always use Command even though it might not be necessary?
Or should I only use Command in the case where more things, menu items, buttons,
whatever, when clicked execute the same code?
Maybe it is good practice to always use Command, or maybe it adds additional
unnecessary complexity. I am new to WPF so please share some advices.
If you're using the MVVM pattern, which is mandatory in every serious WPF application, 'ICommand' is the way to go for every action that is not purely interface logic.
I'll explain:
As you probably know, the MVVM pattern distinguishes between Model, ViewModel and View, where the ViewModel mediates between Model and View. The ViewModel usually holds all the data which is consumed by the view and which you bind your view to. The important thing is:
The View is agnostic of the ViewModel
This means, although your View is bound to the ViewModel, it doesn't reference it, there is no logical dependency to the ViewModel. The 'ICommand' bridges this gap: It kind of packs an action into a bindable property. That's the main point, probably:
A command wraps up an action or function into a WPF databindable
property
And as databinding is the mechanism which, in MVVM, View and ViewModel are connected with each other, the command is the vehicle to perform every action, no matter if it is triggered by one control or by many, that transcends the sphere of pure UI (which is almost everything):
Have a look here (MSDN), where this image is taken from:
If you don't use MVVM I'm not sure whether you need commands at all. There is no significant difference to WinForms then, regarding the UI event handling. But again: MVVM and WPF go hand in hand, in my opinion.
I am building and MVVM application where some of my Models contain the state of realworld-object that their are modelling. The state changes from outside events, e.g. my Model gets information over TCP/IP about a stock that changes, and updates its state to reflect that change.
Now I would like the change to propagate to my View, and the way to do that, is to let my ViewModel know about the change.
I can think of two ways of doing this.
One, I let the Model implement INotifyPropertyChanged, and fire the event when the property changes. However, this seems to be frowned upon for some reason.
Two, I implement an event for each property that can change in the Model, events that the ViewModel explicitly can bind to.
What is the preferred way? Are there other ways (better ways) of doing it?
Edit:
I have now read, both in the comment from slugster and here, that having the Model have a state is not the purpose of the model.
However, in John Gossmans original MVVM post, we find: "The Model is defined as in MVC; it is the data or business logic, completely UI independent, that stores the state and does the processing of the problem domain."
Option 2 is viable, albeit dirty. You can mitigate the dirtiness somewhat by exposing the public events and functions via an interface, and the viewmodel uses the model only via that interface.
Having said that, the model should be treated as a conduit of information, rather than a container for information. This means that ideally your model should not contain any state information. If you have a persistently open channel in your model that needs to notify other components when something is received then I suggest you use the EventAggregator in Prism - this is a weak event pub/sub system, your viewmodel can subscribe to an event of your choosing, and your model can publish that event when it needs to (along with an appropriate payload).
The model classes typically provide property and collection change
notification events through the INotifyPropertyChanged and
INotifyCollectionChanged interfaces. This allows them to be easily
data bound in the view. Model classes that represent collections of
objects typically derive from the ObservableCollection class.
MSDN
I wouldn't say that a Model typically implements INotifyPropertyChanged, but I wouldn't categorically refuse to do so. In simpler - non-PRISM - environments it's totally fine in my opinion.
And then?
To clarify: INotifyPropertyChanged is an interface for the notification in case of a property change, as the name says and most people know. However, it is not more than this, especially it is not WPF specific! Furthermore, as according to the the MVVM principles, the Model should be agnostic of the ViewModel. Therefore, it is clear, that you should use a Publisher(Model)-Subscriber(ViewModel)-pattern (events). That's all. So, as an answer to your question: How to set up the communication between Model/ViewModel depends on your style and the specific task:
If you just want to react on changed properties, just use INotifyPropertyChanged, as that's what it was made for. In the ViewModel, just subscribe to the PropertyChanged-event of the Model and process the changes, which is basically just 'map them forward', that is raise PropertChanged for the ViewModel-property, which is effected by the change of the model property.
Alternatively, if you need to wrap the model changes in a more specific event, lets say 'MyDataUpdated', then I don't see any problem about that as well. Just listen to this event in the ViewModel, and handle it as you wish. That's perfectly fine to.
I hope this helps.
EDIT: As a side-note: I recommend using the PropertyWeaver extension, so that you donÄt mess up your model with all the PropertyChanged-stuff.
I will go with option1. Keep a reference to the model in your viewmodel, however do not use any properties directly. Instead, populate the viewmodel's own properties from the model.Your view model can listen to the property changing notifications for the concerned properties from the Model, and repopulate its own properties from the model. The model is still UI independent, it is merely notifying property changed.
In my opinion, doing your own publisher-subscriber logic other than inotifypropertychanged could be just an overkill as there might not be any benefits doing that. However, this depends on whether you can afford to have a model reference in the view model and my answer is based on the assumption that you can have a reference of model in view model.
For for data binding you can use **Binding**
Data Binding Overview