WPF Prism - load view dynamically in pop up window - wpf

We have multiple project solution based on MS Prism in WPF. For ease of understanding lets take we have project shell, and project usercontrol. The usercontrol project has numerous views for various functions. We have a pop up window in shell project which is called from main shell window, what i want is to load different view into pop up window region manager based on requirement. Any help/suggestion through flow explanation or some code samples will be highly appreciable.
Regards

You can use the PopupRegionBehavior that comes with the Prism-v2 RI to achieve what you are trying to do in a decoupled way. You can read more about it here.
Please let me know if this helps.
Thanks,
Damian

Using a Dependency Injection Container (such as Unity which can also be obtained from the CompositeWPF Microsoft page), you'll be able to pass around an instance of IRegionManager to your various modules/pop-up windows...
For example, in the view you wish to inject another view into, you could have a named ItemsControl:
<ItemsControl cal:RegionManager.RegionName="Modules" />
To fill it with your custom view, all you'd have to do from code is:
_regionManager.Regions["Modules"].Add(view);
(Where _regionManager could be an instance variable populated via Dependency Injection to the constructor of the class it's in). Don't worry about registering the IRegionManager interface with the container, that's done by the UnityBootstrapper during configuration.

Related

WPF PRISM 5.0 & Unity IoC: Trying to implement re-usable view w/ PopUpWindow supporting dependency injection

This is my first post on StackOverflow so forgive me if I am not completely clear.
My WPF project uses PRISM 5.0 and Unity as the container. This is my first project using PRISM and Unity.
In my application, I am loading a View into my MainWindow correctly. This view displays a friendly version of information about an item. I have an edit button on this screen and I would like it to call up a modal window with the appropriate controls for editing this item. So far, I have chosen the InteractionRequestTrigger -> PopUpWindowAction approach as it was the most straight-forward seeming approach to achieve the result. I am not married to this approach.
However, I noticed I am not able to get dependency injection to work for the ViewModel constructor for the View I am trying to use in the modal. This is probably because I have not registered the View with a Region or done any of the associated leg work and the PopUpWindowAction is just plopping my user control onto a plain form if I had to guess.
My question is, can I achieve a modal dialog passing a custom View and ViewModel and have it behave as the parent View and ViewModel calling it? That is, supporting Dependency Injection and the like. After doing the edit logic, I'd like to ideally re-use the View and ViewModel for my add item functionality, but I am thinking I will be registering that View with the "Main Region" of my Shell and as such, would like to use dependency injection there as well.
Hopefully this is clear. I didn't think a code example would really help much here, but if so, let me know and I can put together a simple example illustrating the above.
I would not provide tight-coupling between my main view-model and the view-model for my modal dialog.
Instead, I would consider using the EventAggregator that Prism provides to publish notifications that my main view-model can subscribe to and react accordingly.

is this bad design? MVVM pattern w/ many commands on single class

There are two common command implementations I've seen by Microsoft. One, given by Josh Smith here,
places commands onto viewmodel classes. Another, given by Robert McCarter here, makes commands accessible via a static class (so we can data-bind to them with x:Static). McCarter's approach relies more on the use of singletons and static calls than I want to take chances with, so currently I've chosen to use Josh Smith's approach. However, my "main" viewmodel has blown up in size with at least 30 commands now, as I have a Ribbon control in the main window. Is this a sign of bad design i.e. a lack of separation of concerns? or is this common for MVVM apps? It just seems like a lot of responsibility for a single viewmodel.
I don't think it really matters if you have many commands in the same ViewModel. Commands are just boilerplate code, they don't really implement anything. If the actual implementation of these commands is in the same ViewModel, however, it could be an issue. You should probably try to break down your class into several components to apply the single responsibility principle.
If you have a ribbon control with a lot of commands on it, you're going to need to have a class that exposes all of those commands as properties. It doesn't necessarily have to be your view model; you could, for instance, create a ribbon view model and then expose an instance of it from your view model.
You can't really separate the concerns here unless you have commands on your ribbon that don't interoperate with the view model.
If you are worried of having many command on you MainWindow ViewModel and using a ribbon, you could try giving a separate ViewModel for every tab you have.
In an application I'm currently developing, for example, I separated each ribbon tab into a separate UserControl (which extends RibbonTabItem, because I'm using the Fleent Ribbon). Those views have their on ViewModels. Actually, those ViewModels are dependency injected using a MEF (Managed Extensibility Framework) importing constructor, as well as the tabs are dependecy injected to the MainWindow using its importing constructor. While this approach is probably a gigantic overkill, it has some flexibily. Note that referencing to command on a certain tab from the MainWindow itself isn't a problem, because the MainWindow's ViewModel can have a tab's ViewModel dependency injected into itself and expose some commands of it; or some command can come in form of a specific ViewModel that is injected into all the ViewModels that need it (the latter is probably the cleaner...)

Prism and MVVM for new WPF project

I will be starting a new project soon and am looking for some architectural advice from those of you who have experience with WPF, Prism, and MVVM.
The project will definitely be WPF and I will be implementing MVVM (I will likely use Josh Smith's MVVM Foundation as a starting point) in order to be able to benefit from the separation of UI/logic etc. I am not sure though if I would benefit from using Prism as well to structure my project.
Let me briefly describe the project. There will be a main "toolbar" that will display a number of widgets. Each widget displays some basic data related to its function and clicking the widget will open a new window that will display much more detailed data and contain a rich UI for viewing/editing the data.
Now, I was thinking that I can use Prism to frame the project but I have never used it before and am not sure if it is suitable for what I am trying to achieve. For example, would my "toolbar" be a shell that contains regions that each widget would populate? Would each new window that is displayed when a widget is clicked also be its own shell with its own region setup? If I can get the pattern down for the toolbar and one widget on the toolbar, I can replicate it for the rest of the widgets.
Aside from Prism, I have a question about how MVVM should be implemented for certain data editing windows. Let's say I have a chart that displays some data and the user is able to directly click/mouse move on the chart to edit the data that he sees. All of the data is in the model and the view model is making that data available to the view via binding. My question is where will the mouse click/move events, that are specific to the chart in that view, be written? We don't want much/anything in the view's code behind and we don't want to have UI event handlers in the view model so I am not sure how this type of scenario is handled. I know that commands are the likely answer here but the MVVM samples I have seen usually show sample commands for simple button clicks. Is the general idea the same?
So, if anyone has any suggestions on the above or any general tips on working with WPF and MVVM/Prism, please let me know.
Thank you.
There are a few questions in there so I will do my best at covering them all.
I worked on a project that had WPF, MVVM, and Prism along side other frameworks. The best advice is to understand the power and functionality of each before glueing it all together. You don't have to use all the features of Prism for it to be useful in this situation.
For Prism you can use...
Shell and bootstrapper to initialise the application and load modules from other assemblies.
Create and configure Unity for Dependency Injection. You can use other DI Containers. Here you can add global services each module will use.
Use of EventAggregator to notify differnent parts of the application, usually across modules and views
Regions for naming areas on the UI so modules can add a view to a particular location.
The above 4 don't all have to be used but can easily be integrated in a MVVM /WPF application.
For example, would my "toolbar" be a
shell that contains regions that each
widget would populate?
Here you can have a region you create (you can derive from Region) that will manage the buttons on the toolbar. (I have used a region with regards to a Ribbon). A service can be exposed via an interface that each module can supply the command/image (what ever you have) that when it is clicked will create a ViewModel. You can do this inside the module's Initialisation.
Would each new window that is
displayed when a widget is clicked
also be its own shell with its own
region setup?
If each button opens a brand new window I would suggest introducing a common controller class that will create a generic use window and attach a view model that your module creates. No real need to use regions in this case unless you are gluing different views to a application window that stays open longer than the life of the view itself. The window in basic form can simply be this...
<Window ...>
<ContentControl Content="{Binding}" />
</Window>
Where within your controller it can do this...
public void DisplayView(ViewModel vm)
{
var window = new MyWindow { DataContext = vm };
window.Show();
}
The controller can be used within your module directly of wrapped within a service... although for testabilty a service and interface would be best. Make sure you have merged your module resources with the Applicaiton.Resources and use DataTemplate's to link your view to the view model.
My question is where will the mouse
click/move events, that are specific
to the chart in that view, be written?
Don't be afraid of code behind but you can in this case use EventToCommand attached behaviour that will route to a command on your viewmodel. MVVMLight toolkit has this which you can reuse if you want.
DI is very powerful and I encourage using it even without Prism as constructing your view models will be easier.
HTH
I think Prism will work great for you.
->would my "toolbar" be a shell that contains regions that each widget would populate?
Put a single region with an ItemsControl in the Shell
Create modules for each widget
Keep adding the widget modules to the same itemscontrol shell region.
The biggest advantage with this is that if you add more modules you don't need to change anything.
->Would each new window that is displayed when a widget is clicked also be its own shell with its own region setup?
No, you can use a 'WindowRegionAdapter' in the shell to create views for your widgets in separate windows.
->where will the mouse click/move events, that are specific to the chart in that view, be written?
You can use attached behaviors to bind events in your view to commands in the ViewModel purely in XAML. Google 'Blend behaviors' or 'attached bahaviors' for how you could go about doing it. There is no need to write any code behind for this.
To be honest I am only trying to give you the keywords you'd want to search to get all the information you need.

WPF how to integrate Ribbon in prism applications

I'm writing a prism application and would like to integrate Ribbon library in it. I want a Ribbon Window that would be used as a Shell with office-like tabs and tab groups. The modules should be loaded on demand depending on the tab selected by user. I don't want the tabs to be located in a region if this is avoidable. So I created a Ribbon window and some regions and get all kind of errors (cannot resolve dependency object, etc.). Is there somewhere a good example of such application or a tutorial? How to load the modules depending on the user's choice?
I started this thread but I didn't get an answer that could help me.
Thanks for any help and suggestions.
Have you implemented a RegionAdapter for the Ribbon? (I'm guessing you're trying to fill the Ribbon dynamically with a Region attached property)
See this link for details.
Make your shell a RibbonWindow and if you need commands over the whole application you can create applicationcommands.

Will PRISM help?

I am considering building a application using PRISM (Composite WPF Guidance/Library). The application modules will be vertically partitioned (i.e. Customers, Suppliers, Sales Orders, etc). This is still all relatively easy... I also have a Shell with a main region were all the work will happen but now I need the following behavior: I need a menu on my main Shell and when each one of the options gets clicked (like customers, suppliers, etc) I need to find the module and load it into the region (Only 1 view at a time)?
Does anybody know of any sample applications with this type of behavior? All the samples are more focused on having all the modules loaded on the main shell? And should my menu bar also be a module?
[UPDATE] How do I inject a module into a region based on it being selected from a menu? All the examples show that the module injects the view into the region on initialize? I need to only inject the view if the module is selected on a menu?
Yes PRISM will help you out here.
A number of things here worth mentioning.
RE: Is Prism right for me?
You can load a Module on Demand. PRISM has the capabilities of loading a module at RunTime, so in your case if you bootup the said solution using Shell and ModuleA. Your user then triggers an event (ie Menu choice) it can then allow you to dynamically load ModuleB and then inject that into play. To be clear though, you really need to sit down and do your homework here as you need to ensure ModuleB doesn't have any of its own dependencies on other modules etc (typically its wise to use an Infrastructure Module. I've used techniques where i have a manifest of modules that i lookup in XML that lists its absolute dependencies and then I make sure they are loaded first, then I load ModuleB).
See Load Modules on Demand via PRISM help docs (Development Activities). Also lookup Prepare a Module for Remote Downloading
RE: Injecting a view at runtime
To inject a View into a Region via Menu is a simple case of accessing the IRegionManager and then adding it. To do this, make sure in your Constructor for the said ViewModel/Presenter/Controller you're using put:
MyConstructor(IRegionManager regionManager, IUnityContainer container)
As with PRISM you can pretty much add any object you want into your construct and PRISM will ensure it arrives there on time and on budget (hehe).
From there its the normal approach you'd take with adding a view... eg:
IMyViewInstance myViewInstance = this.container.Resolve<IMyViewInstance>();
IRegion myRegion = this.regionManager.Regions["YourRegion"];
myRegion.add(myViewInstance);
myRegion.Active(myViewInstance);
And all should come together! :)
Note:
Make sure you set a local reference to the container and regionManager at Construct (this.container = container etc).
If you're not sure where the above namespaces exist, right click on IUnityContainer for example and let Visual Studio RESOLVE it (right click menu)
Put the Add logic into your Menu Event that or use a central method - whichever blows your hair back :)
Scott Barnes - Rich Platforms Product Manager - Microsoft.
Just finished watching Brian Noyes on Prism at dnrTV. This answered all my question...
It's not clear what you mean saying "find the module and load it into the region". You can load module's view and add it to shell. Composite UI app block and CompositeWPF are built on top of the IoC pattern. It means that your modules should inject their menu items in shell's menu strip or subscribe to events generated by shell.
You could have your main region be a ContentControl, this way only 1 view will be active at a time.
You can also load your modules "On Demand". There is a Quickstart that shows you how to do this. You should also keep in mind that if the module was already initialized once, initializing it for a second time will not execute the Initialize() method on the module.
It might be useful that when you click on the menu, this will load the module on demand (which will not load the view yet) and then you can fire an event through EventAggregator, so the module can now add the view (use the named approach for not adding the view twrice) and the Activate the view (which will make sure the view is shwon in the region).
Hope this helps,
Julian
to save you time, check John Papa's Presentation Framework article. It will be more easy if you have 3rd object(Screen Conductor) to handle your screens in showing or hiding from regions.

Resources