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.
Related
I need to build our future business applications with WPF using MVVM.
My typical application consists of several windows/tab pages with grids and form style windows. Both edit windows and grid windows can be different depending on the logged in user, so most of them will be built datadriven.
And I'm trying to write as few code as possible, as not written code is the only one to be guaranteed error free .
So, now my question: how to structure the entire thing?
The View is clear to me - is is built using XAML or by code.
The ViewModel should contain the business logic and the validation rules and should let feed the View the data, and should contain the commands for the actions.
So, where to put the data? A select returns a DataTable. Should this datatable exposed through the ViewModel to the View for the grid windows?
And for the form windows? Should the single DataRow exposed trough the ViewModel to the View?
Are there other helper or intermediate classes needed?
Thank you for any useful suggestion!
Wolfgang
Its best way to go with WPF and MVVM,
I suggest before you start go thru the basics of MVVM. for your reference you can understand better here
The preferred UI paradigm in WPF is to have tab controls and grids in a single window, something like this:
You don't have to stop there, you can nest them as deeply as you need to for the sake of clarity.
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.
We're doing a WPF application using Prism.
We're using the 'view-first' approach where our views are injected with the VM (IFooViewModel).
We want to hook up a UI action in a view to display a modal dialog box. We want to do this the 'proper' Prism way, i.e. just specifying a URI and not hard-coding a particular View or ViewModel.
There seems to be very few examples of achieving this seemingly trivial goal.
As I assume you are also using the DI containers from PRISM, you can try using Inversion of Control. Basicly what you do is the following.
Each view has it's own interface. In that interface you define your code with events and such. You then inject the Interface into the viewmodel without it ever knowing anything about the view. Except the necessary events of course
I am very new to WPF and am trying to set up an application that requires switching of views.
For example, a user is viewing a system that contains a number of components, when they click on a component, it should switch to a view that is associated to that component, replacing the previous system view. It's my understanding a Controller should be used here but the implementation eludes me.
I have found a few examples, but the projects are a bit too large for me to actually follow what is going on specifically with the view switching. What would really help me here is some example code from the Unity setup in the App file that allows multiple views, the Code in the controller that switches the view, and the code associated with a button that makes the controller switch the view.
Thanks
If you are just beginning with WPF and diving directly into using IoC/MVVM, then you may want to consider taking a step back and starting with the WPF fundamentals, i.e., layouts, routed events, commanding, binding, dependency properties, INotifyPropertyChanged, etc...
To get you started: tutorials on wpf and mvvm.
For most of us mere mortals, WPF has a steep learning curve. Yet, once you make it over that first hump, the 'aha moments' start kicking in on a regular basis.
I'm using Mvvm-Light, but I believe Unity will be similar.
You should have a ViewModelLocator where you register ViewModels.
You should have somewhere styles or datatemplates that tell the framework what view to show depending on the view model encountered.
You should have some property you bind to, that is a base view model.
From there, all you'll have to do is change that property to a different view model, and your view will update accordingly.
As Metro said, steep learning curve, but once you get used to it, it starts to make sense :)
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.