I'm redesigning an application to work with prism. The current application has some open/save/save as, ... routed commands implemented in a viewmodel that corresponds to a shellviewmodel. Usig a behavior the commands are added to the window's commandbindings. In the new design this logic doesn't belong in the shell but in a module.
To complicate matters this module doesn't have a view active before an 'open' command has been handled. So even if I were to add to the commandbindings of a view this would not work because there would be nothing to route to. I do have a view that is added to a ribbonbar but that works through an adapter that merges with the shell ribbonbar and detaches the merged elements from their old parent into the main ribbon, preserving the DataContext of each element (similar to https://prismribbonregionadapter.codeplex.com) It doesn't feel right to try and put add to the commindbindings there just to make it work.
This seems like a common problem and yet I'm not finding any information about it. Would it be a good idea to use a service for this somehow? Let the shellvm bind to the shell commandbindings and expose those through an interface? Any advice on how to tackle this?
Related
my problem is that i have a CoreAPP, in this core app there possibility to active different modules (M1,M2,M3).
CoreApp have a view coreAppview. On that view if M1 is activated than i need to show an aditional button.
Right now there is just a simple if statement which just check config and add button if M1 is activated.
I dont feel very comfortable with just a single if statement between Core functionality and aditional module functionality and i want to be sure that some other developer dont just remove this check.
Are there any ways to decouple this functionality from the Core view in some way?
This can be done using plugin architecture.
You will need:
main view model. It will contain collection of loaded and activated plugins;
some way to load plugins (e.g. MEF);
DataTemplateSelector, which will load data template for plugin's view model. You can implement some convention-based search, e.g., if plugin's view model M1_ViewModel is placed in M1.dll, then load data template from M1\Views\M1.xaml;
items control (ItemsControl, ListBox, etc) in your main view. This items control will hold plugins collection and will use mentioned selector to load appropriate view.
A more generic solution would be, to add somthing like "GetAvailableActions" to the module's base class. Then, your CoreApp can call that method after a module was activated and generate the corresponding buttons in the view.
I currently have a viewmodel such that it has a grid full of appointments. I would like to double click and open up my CalendarView with the editappointmentdialog opened for the record that was selected. May I ask how would I do that in an MVVM style?
I searched the internet and found this RadScheduleViewCommands.EditAppointment.Execute(appointment, this.scheduleView); but I don't have access to the scheduleView object from the MVVM. May I ask how abouts I should do this?
I think I can achieve this if I relay it back to the view, but I'm trying to look for another approach.
The issue you have is that you can't open a view from a view model as it'll break the MVVM design pattern.
There are a couple of ways you can open a view from the view model without too much hassle:
Implement a Messenger service to publish an event to the view, like MVVMLight does.
Straight up add a Click event handler on your button and open the view in the code behind (It's still view code after all).
However my preferred method is to use an ICommand, or RelayCommand. I have written a repository on GitHub which demonstrates how to achieve this.
I have an application which use plugins. Each plugin is developped following MVVM, so I have a View, binded to a View-Model inside. like the following picture:
In my application I have a Designer, when I add any ViewModel in my ViewModels list, its view will appear in the Designer.
My question is: How can I keep this binding when adding the viewModel of my plugin in my list ?? how to make its view appear in my designer ?
This is an interesting question... and like always there are many ways to accomplish it.
It depends what your plugins are.
If the plugin is more integrated and not so isolated. You should think about some Factory classes which are for example named like ViewResolver or ViewModelResolver. They can take parameters like the name as string, a type, a type of an interface or work by conventions.
Purpose is to find the VM for a view and vice versa as a central service. This service should also locate plugin VM or import them for example with MEF.
For more info’s google on view-first, viewmodel-first, view viewmodel marriage, etc.
Or
If your plugins are fully fleshed out components which run independently. I would suggest your host application should have in its viewmodel a list of components which are the plugins. So the Model will be a Component no matter if it contains the view and everything else because of the hosting app is to manage the components. So you would have an ObservableCollection which are bound to content control. The content control can then host the plugin as a whole.
These are two possible ways... like I mentioned above there is no "the" way in mvvm and it always depends on your use cases...
But I hope this guides you in the right direction...
HTH
Thank you for the answer #Silverfighter! it made me things more clear !
I found a very intersting article wich seems adapted to my problem
The solution is here:
http://www.alphablog.org/2012/05/07/simple-plugin-system-based-on-ninject-and-mvvm-light-2/
I am currently building an MVVM based application. The application should also have a wizard in MVVM style. The wizard is not a normal wizard, its a particular kind of a wizard. My goal is to implement a wizard with
1.) has also multiple branches. The wizard can guide you in other direction. So the wizard must not be straightforward.
2.) can also have short cuts. You can skip some pages where default values are setted.
3.) is also normal - straightforward.
Note, some information in the wizrad pages are on-the-fly. That means, that the information can be passed between each step and processed.
Are there any approaches like patterns to solve my problem? How do I implement it the best way?
Did you read this good article in Code Project about Wizard in MVVM and written by two MVVM guru:
http://www.codeproject.com/KB/WPF/InternationalizedWizard.aspx?display=Print
You might have a look at the ViewModel sample application of the WPF Application Framework (WAF). It shows how to implement a Wizard in a MVVM way.
If your wizard has a single VM that stores the state/results of each step and sits behind a view that is a user control...
You could have a Frame on the wizard view that requires 2 events in the code behind (This obviously depends on if your MVVM architecture can live with this?).
Event 1) When the binding of your wizards step raises its NotifyPropertyChanged: tell your frame to "Navigate" to the appropriate page (as described in a property in your wizard VM).
Event 2) On the frames "Navigated" event so that you can point the current pages data-context at your VM.
This way the wizard viewmodel controls the state of the wizard from start to finish and it also can describe the steps, which can easily be added to, edited, etc.
Obviously this may not sit well with everyone's view of MVVM.
I am working on a WPF app and the UI is getting a bit complex to manage. I am looking for advice on how to maintain it as it grows.
The layout looks something like this
<Grid>
<List of Objects View/>
<Objects Relationship View/>
<Object Details View />
<Multiple Objects Details View/>
<View 5 />
<View 6 />
:
:
</Grid>
Each view gets created (visibility hidden) and bound to some complex data, when the window is constructed. I want only one view visible, to the user at a time. I do this by manipulating visibility.
But the problem is the transition between views doesn't involve just fliping Visibility. It involves rebinding with currentdata, stoping background threads/timers and starting new ones (and possibly some binding again) that support the newly selected view. So what's happening is with every new view I add, I am adding a whole bunch of code to take care of all the possible transitions.
Is there some pattern I can use to deal with this kind of scenario?
Also is there some way I can avoid creating and hiding everything at app load and using visibilty as a controller?
Any help is greatly appreciated. Thanks!
May I ask how you are allowing the user to switch back and forth between the views? Is it a key combo? Mouseclick?
Not that it's answering your question per se, but my suggestion is that this sounds like a perfect scenario for a tab control. And with WPF, it doesn't necessarily have to look anything like a tab control.
If you use a TabControl, it opens up the possibility of using the SelectionChanged event coming off of the TabControl to allow you to tell background threads to stop and you can unload anything that you need to unload.
Depending on how you use the TabControl, the UI can be somewhat virtualized. What that means is that whenever a tab is unselected all of the UI for that tab is destroyed and recreated the next time it's selected. It will behave this way if you use the MVVM or PresentationModel pattern and load ViewModels as the items for your TabControl and use DataTemplates for the views. If you just put TabItems into the TabControl with controls inside of them, it will not behave this way, however.
As far as patterns are concerned, I'd definitely recommend MVVM. It may take a bit of time to catch up to it and understand it, but I'd never do WPF without it. If you need anymore resources or examples, let me know.
edit:
I reread your question and noticed that you may be in need of another type of navigation. If you've got views that are needing to make transitions to other views based on user actions and you don't want all of the views to be presented to the user so that they can select which one they want to look at (like the TabControl will do), you may want to look at WPF Navigation. Navigation is basically something that MS added in with WPF to allow browser style navigation in a WPF app. This MSDN article should be a good resource on that kind of thing.
This sounds like a problem well suited to Composite WPF (Prism). You can define your main area as a region, and use a SingleActiveRegion to show one view at a time. If you create your own region adapter, you can do all the maintenance when the active view changes.
Also, adding a new view won't involve changing the hosting view's code. This will allow you to deploy additional views in the future in separate assemblies...