In my WPF (4.0) application I'm using Viewmodel-first pattern. Hence, my viewmodels are created first, then the views - using data templates. A working demo can be found here.
Now, from within the created views (code-behind), I need to modify a property of the viewmodel. In a View-first approach, I would simply access a named viewmodel instance. However, the Viewmodel-first approach does not allow for this. There is a viewmodel, but the view does not care what it is.
BAD:
Sure you can get hold of the DataContext and use it, but that effectively couples the view and t
the viewmodel.
private void MyView_Loaded(object sender, RoutedEventArgs e)
{
this.viewModel = DataContext as MyViewModel;
}
There has to be a recommended pattern for this. Commands? Messages? Please help!
Q: How do I modify (set a property) the active viewmodel?
Use Bindings to pass data from View to ViewModel and commands to active the ViewModel.
Commands should use a binding to a execute a Command on the ViewModel.
Messages should be used to communicate between ViewModels.
.
You can't do that. Otherwise View will be aware about View Model.
If this initialization is common across all view models, then you can define the properties/events in ViewModelBase and derive all view models from this class.
Q: How do I modify (set a property) the active viewmodel?
You need to use EventAggregator pattern for View-ViewModel communication.
You can use your favorite MVVM framework, and nearly all framework support EventAggregator (or MessageBus or Enterprise Bus).
Related
Currently I'm learning C# with WPF. My mainapproach is to use the MVVM pattern the best I can but now I'm a bit confused.
In my Application for all my views I have a viewmodel:
private DruckviewViewModel ViewModel { get; set; }
public Druckview()
{
ViewModel = new DruckviewViewModel();
DataContext = ViewModel;
InitializeComponent();
}
Is this the suggested way to implement the ViewModel into the View or are there better ways to do it?
MVVM doesn't mean no code-behind.
MVVM is the pattern of separation of concerns. It helps to separate your application's architecture to the three parts(in order of appearance):
Model
View
ViewModel
Where Model is class containing your business logic.
View represents your view class which contains only view related logic(XAML and code-behind) It is Ok to have code-behind unless code contains only view's logic (for example in button click eventhandler you copy color of one textbox to another, which of course can be done in XAML, but from MVVM point of view it is not important)
ViewModel represents View's behavior without any reference to the View.
Notice that for example this property on my opinion will violate MVVM pattern, because Visibility is view related type
public Visibility MyVisibility { get; set; }
So dependencies between parts of MVVM goes like this:
Model doesn't know about anything
ViewModel know only about Model
View know about ViewModel
View ---> ViewModel ---> Model
I think for using MVVM is not important how tightly View bounded to the ViewModel. It is already bounded, because you use ViewModel's properties and commands.
Not bounding tightly (for example using interface as ViewModel) will give your possibility to test View without real ViewModel by creating own "design-time" viewmodels for example.
If your current solution works and satisfy your needs and you just starting with MVVM and WPF then continue with that until you meet need to fully isolate View from ViewModel's types
This will work, but it isn't really true to the MVVM pattern, as the View is now directly tied to the View Model.
Most existing MVVM frameworks use the concept of a View Manager. A class that creates a view from a view model instance, connects them together, and displays the view. You would end up with something like this:
DruckviewViewModel vm = new DruckviewViewModel()
ViewManager.Instance.DisplayViewFor(vm);
It would figure out, based on naming conventions, that DruckviewViewModel uses the Druckview. It would create the view, set the DataContextProperty, and make the view visible.
Without using one of these frameworks, this is a lot of work to build on your own, but this is considered a "Best Practice" pattern.
You may want to consider using an existing framework, a good list comparing their features can be found here.
BTW, if you are wondering how to get intellisense in the XAML designer without setting the DataContext in the constructor of the view. The proper way to do it is to add a design instance in XAML, with an attribute like this.
d:DataContext="{d:DesignInstance local:DruckviewViewModel}"
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 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.
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.
I've got an AllTopicsViewModel and its got a property ExerciseVM which is an AllExerciseViewModel, since I want to be able to refresh the AllExerciseViewModel of an ExerciseView so I am doing it like this (not even sure if it violates MVVM, pls. tell me). Well, I want to convert the 2 lines following the InitializeComponent to XAML but not sure how, can anyone help me out?
public MainWindow()
{
InitializeComponent();
AllTopicsViewModel vm = (AllTopicsViewModel)topicsView.DataContext;
vm.ExerciseVM = (AllExercisesViewModel)exercisesView.DataContext;
}
Yes, this is a misconception, according to the idea of MVVM.
Ideally, your View's codebehind (view.xaml.cs) contains nothing more than the auto generated code. Your view only accesses the ViewModel via WPF's data binding mechanisms. Because data binding via WPF is a loose coupling between the binding view and the bound-to ViewModel, you achieve the seperation that drives people to use MVVM.
You are retrieving the ViewModel in the Views codebehind from your control's DataContexts. With this, you create a strong reference between View and ViewModel. So, to help you with your question: You should think about what you are trying to to do with your ViewModel in the View's codebehind and how you can do it differently, either in the view's XAML or in the ViewModel's code itself.
If you like, post the complete MainWindow() class for some advice...
EDIT:
Ok, so its just about setting the child ViewModel on the parent ViewModel. The parent ViewModel AllTopicsViewModel should be responsible for setting its own ExerciseVM on initialization. This is not the View's job. the parent viewModel should assemble the data from one or more models and then create the child view models which the view consumes. Does that make sense for you?