Advanced Navigation in WPF MVVM Application - c#

I'm developing a WPF based MVVM application and have a question relating to the best way of approaching view navigation within my application. Specifically, I am interested in the cleanest way to approach this navigation when I have multiple views that can cause navigation.
Let me summarize my current application layout so that I can better explain the problem.
The diagram above shows the rough layout of my main shell. The Main Navigation area is static and provides a number of buttons. Buttons exists for primary application functions such as Status, Configuration, Diagnostics etc. When one of these buttons is pressed, the content of the Contextual Navigation area is set. Specifically, this achieved by having the contextual navigation area contain a content control with the Content property bound to a single property of type ViewModelBase. In addition, the view models and views are tied together with data templates in the application resources.
The specific view/viewmodel populated in the contextual navigation content control then provides addition navigation options that are relevant to the primary function selected in the main navigation. When an option is selected in the contextual navigation, the main content region is updated in exactly the same way as described with the contextual navigation previously.
So I suppose you could describe the combination of MainNavigation and ContextualNavigation areas something very similar to an Outlook Style menu bar. i.e. primary selection at the bottom, secondary selection at the top, resulting in a change in main content area.
Now to the problem. I can make this work, but it's starting to get very messy! I've got the MainNavigationViewModel causing navigation, and multiple contextual ViewModels that get populated in to the ContextualNavigation area causing navigation. On some occasions, it may be that an action in the main content area also creates the need for navigation also. I've also actually got a Ribbon control that may also cause some navigation. So I've got navigation everywhere spread throughout my ViewModels and I don't believe that it is maintainable. PS. In case you were wondering, I'm currently using a messenger system to allow decoupled communication between view models.
I'm starting to think the best approach is to create an abstract service that takes care of navigation for all the view models within my application but not sure what that would look like. Am I on the right lines here and if so, does anyone have any suggestions for an application wide navigation service that handles navigations from multiple view models?

first of all what MVVM approaches are you using? View first or View Model first?
the right choice can make you life easier.
The idea you already have go's into the right direction Interfaces and inheritance - abstracting the navigation layer.
if you already use Messanger it's actually follows a similar approaches.
in your case an architecture plan would be more than necessary, take yourself time and draw it down.

Related

Xamarin Forms : using Prism and/or ReactiveUI, is it possible to achieve vertical slicing?

I have been working on a mobile application for one week, for personal education and enhancement. I have some experience with WPF and MVVM, I have no experience with mobile development.
The idea is to make a cross platform application, while testing some coding philosophies :
Reactive programming (ReactiveUI)
Vertical slicing, if possible (blog 1, blog 2)
I plan to use the following components :
Prism.Unity.Forms : seems to provide application structure, ioc, navigation, seems widely used, and done by top notch people
ReactiveUI, ReactiveUI.XamForms, ReactiveUI.Fody : WhenAnyValue, ObservableAsPropertyAttribute, ReactiveAttribute (tutorial), not using them looks like a huge missed opportunity to me
The current structure of my Visual Studio is the following :
Csproj
ViewModels
CreateExercisePageViewModel
HomePageViewModel
Views
CreateExercisePage
HomePage
I managed the following :
Set the HomePage as the initial Page, contained inside a NavigationPage, by using the navigation functionalities of Prism.
Declare a named button in XAML, set its Command property through a OneWay binding created in code behind, using ReactiveUI functionalities (like shown in the tutorial, using the WhenActivated method)
Navigate to the second page (CreateExercisePage), using Prism navigation
One issue is that, even though I have seen a few articles regarding vertical slicing, there were mostly about web applications.
So the question is : Is vertical slicing applicable to mobile applications ?
I would like to restructure my project by using vertical slicing, but having troubles finding articles about Xamarin Forms, I feel uneasy.
Edit : my understanding of the vertical slicing concept, is that you should group code, related to a feature, in the same physical space (folder). By doing so, it gives developers a huge hint about the cohesion of those files.
Given a mobile application is made of screens, I assumed grouping code by screen, regardless of their type (presentation, logic, persistence) would make sense.
Rewriting the application would give the following csproj, then :
Csproj
Screens
Home
HomePage
HomePageViewModel
CreateExercise
CreateExercisePage
CreateExercisePageViewModel
Adding a new screen would mean adding a new folder to the "Screens" folder, reducing the risk of modifying existing files/logic.
Vertical Slicing is a little bit like MVVM which we are utilizing on Xamarin.Forms:
https://learn.microsoft.com/en-us/xamarin/xamarin-forms/enterprise-application-patterns/mvvm
The view is the UI layer, view model helps you handle the logic code and model represents your database data.
For instance, a user clicks the button on view layer to trigger a command in the view model. Then this command could add a new product to the List property of that view model. As this list property has been changed it will notify the UI to respond to this action.
Moreover, your first architecture is more appropriate:
ViewModels
CreateExercisePageViewModel
HomePageViewModel
Views
CreateExercisePage
HomePage
Make your pages separated by your view models.

Create Single Window Navigation in WPF

I want to create a kiosk mode application using WPF. I want to use a single window because the user should not be able to exit this fullscreen application.
The application should guide the user trough a process. When the user proceeds trough the process, the screen should constantly change and show him the next step.
Usually I just create a single window and use a "state machine" to switch UserControls containing the information for the current step. Is there a better way to achieve this functionality? Maybe I would get a better result using multiple windows or Pages (never used them).
The reason why I am asking is that in future I want to have a simple, clean way of switching the content inside a single window. i.e. I am planning to implement some sort of animation when switching content (like sliding to the next / previous step). I don't want to put more effort into my current approach if it isn't the most flexible and clean one.
Any ideas?
PS: This is about desktop applications. Today I come from the Winforms environment and am experimenting with WPF.
There's a few ways you can achieve this.
First would be to use a Page based application, this will allow you to use a single window. Here is a pretty interesting tutorial
A bonus of using this approach is that navigation between pages is built in.
Your requirements are that you need to use animation for transitioning between pages, as far as I'm aware, using a Page based application cannot achieve this (I may be wrong). So your other option would be to use a UserControl MVVM approach.
This probably won't make a lot of sense now, but here goes:
You can use a single master view model which will hold multiple child view models, each of these could have a visibility property which dictates the visibility of the associated view. The master view model would simply be responsible for displaying the appropriate view model depending on where the user currently is in the application.
Using some clever XAML, you can create storyboards (animations) when the view becomes visible, which will allow you to achieve the crazy awesome animations that you require.
Anyway, that probably didn't make any sense, so here's a tutorial to get you started with MVVM.

Prism regions for WPF application with Ribbon control on top

I have WPF app with ribbon control on top. I am new to Prism, and
I wonder what do you think about regions. Should I have just two regions,
one for the ribbon part on top and another region for the rest. It will be simple app
wtih ribbon on top and more views in the rest area.
You should determine the regions based on the layout of your application.
If your application has ribbon and a main content area, and your main content needs to change while the ribbon stays the same or the ribbon changes when the main content changes. then having 2 regions sound smart to me
Prism region navigation is done through the INavigationAware interface which lets you control the navigation to/from a certain view.
Changes are sometimes inevitable, but they might affect your INavigationAware implementation. So to avoid changes of your logic, it's best to first design the layout as detailed as you can.
Also, Don't confuse between regions and views. You can have 1 main content region in your main view, and multiple views to display your content in varies layouts. that doesn't require additional regions.
Think of all your test cases and see if you can implement all of them with two regions.
Good luck

Model View Control in C#

Designing a presentation type application which consists of 2 forms, the first form will be used to control the presentation so it can be manipulated on the fly, it will be based off the first monitor of the pc, the second form will be on the second monitor (or projector). I need to update the second form with numbers and pictures during the presentation. In terms of accessing information between forms, would MVC be the best way to do this?
http://www.c-sharpcorner.com/UploadFile/rmcochran/MVC_intro12122005162329PM/MVC_intro.aspx
Cheers!
You don't make it 100% clear if you're are using Forms or WPF (you've put both tags) if you are using WPF the most popular and comfortable design pattern for is generally the Model-View-ViewModel (MVVM) pattern. Is this is quite close to MVC but slightly different. You can read about it here
http://msdn.microsoft.com/en-us/magazine/dd419663.aspx
In your application it would mean having data classes that described and manipulated the presentation itself (the model).
Then you would have a view model class (or group of classes) that describe what's visible in each window and the current state of the controls and the currently displayed slide etc. both sets of view models bind to and update the same underlying presentation model.
Finally the XAML and controls render two a 'views' one for each window, the views then become nice and clean binding only to the current state of the ViewModel.
Hope this general outline provides helpful inspiration, if you want and more specific info or advice please ask.
Mark

WPF: UI Composition

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...

Categories