When should I use a UserControl instead of a Page? - wpf

I notice that many of the WPF MVVM frameworks seem to avoid using the NavigationWindow and Page controls in favor of composing pages using nested UserControls.
The NavigationWindow and Page provide easy ways to enable back and forward navigation in the journal as well as providing an easy way to pass data among pages. Most MVVM frameworks I've seen re-implement these features in various ways.
Is there a specific reason to avoid using NavigationWindow and Page?

"NavigationWindow does not store an
instance of a content object in
navigation history. Instead,
NavigationWindow creates a new
instance of the content object each
time it is navigated to by using
navigation history. This behavior is
designed to avoid excessive memory
consumption when large numbers and
large pieces of content are being
navigated to. Consequently, the state
of the content is not remembered from
one navigation to the next. However,
WPF provides several techniques by
which you can store a piece of state
for a piece of content in navigation
history...."
http://msdn.microsoft.com/en-us/library/system.windows.navigation.navigationwindow.aspx

I just discovered another difference between UserControls and Pages: Pages cannot be used as DataTemplates.
For example, if you were creating application using the MVVM style, you might expect this to work:
<DataTemplate DataType="{x:Type ViewModels:ProjectDashboardViewModel}">
<Views:ProjectDashboardView />
</DataTemplate>
But if the ProjectDashboardView is a Page, it will fail.

I just found some other interesting information related to WPF NavigationWindow and Page on Paul Stovell's website.
He has this to say about the NavigationWindow class:
WPF includes a class called NavigationWindow, which is essentially a Window which also doubles as a Frame, by implementing most of the same interfaces. It sounds useful at first, but most of the time you need more control over the Window, so I've never had any need to use this class. I am just pointing it out for the sake of completeness, though your mileage may vary.
See his in-depth article on WPF Navigation and the Magellan and WPF Page management issues he encountered when writing his Magellan WPF framework.

Well, you're still going to use usercontrols to create reusable sub components, but as for app architecture, it comes down to use case really. If you're building a typical web application a Business/Navigation App should be fine. If you're writing a game, not so much. Likewise if you're doing something like an interactive advert or media player.

Related

MVVM Light Views - Page vs UserControl

Can somebody help me understand what the real difference is and why the MVVM Light toolkit users UserControl's for Views instead of Pages? I know there are some inherient differences between UserControl's and pages like access to the "NavigationService" on a page.
And some of the examples from John Papa's implementation of the MVVM Light use Page instead UserControl, but if you use the MVVM Light "View" Template it uses a UserControl.
thanks
dbl
A Page within a Silverlight application is designed to be hosted within a Frame - and is part of the navigation framework (see the MSDN Navigation Overview documentation). Applications of this style navigate from page to page, with the URL updating to reflect the current location, in much the same way as HTML-based websites.
A UserControl, is a re-useable unit of your user-interface. It is typically composed of a number of controls, UI elements - and may have some code-behind to perform logic.
If MVVM Light used Pages instead of UserControls, the framework would only be useful for navigation-based Silverlight applications, which are not terribly popular. However, UserControls can be hosted inside any other Panel or Page, therefore this approach is more flexible. A UserControl can be used as the content of a Page, but can also be used in many other contexts.

WPF, MVVM, Shell and UserControls

I am building a WPF app that is based on the MVVM pattern (using MVVM Light). It has an outer "shell" to it that gives the main look to the app (status bar, etc.) and then all the content is contained in various user controls that I swap out with the Telerik RadTransitionControl. My two questions related to this are as follows:
I am building my ViewModels using the ViewModelLocator part for Blendability purposes. This involves a basic static class that returns a new instance of a ViewModel for binding and instances are essentially shared as long as the app is running. The question for this is whether I should use a concept such as a "ViewLocator" in that it is a static class that has a static property for all of my views (the app has ~10 so it's not huge) and when I need to transition to a new view I just pull from the static set. The pros of this are ease of use, but are there cons? Is there a better way to pursue this?
What is the best way to transition views? Currently I am passing an enum to my shell view (via messaging) to indicate which view I need, but this seems really hacky and doesn't support passing certain views arguments. I toyed with a custom class, but I would almost need a different one for every view and it seemed like it might be overkill. What is the standard practice executed by WPF devs for this process?
Thanks in advance for the help. I'm fairly new to WPF so I want to make sure I learn the industry standards and avoid hacks wherever possible.
I work on an application that uses the same pattern. We have a static locator and reference the same ViewModel every time we switch to a different part of the application (details view, list view, map view, etc.) We have had a lot of success with the ViewModelLocator pattern - it is pretty easy to understand. We have not done significant testing with running the application for multiple hours.
We use a TabControl with the tab styling removed to transition between the main screens of the application. This gives us one point of entry (the selected index property that we bind on the "naked" Tabcontrol) to change the major screens of the application. For now, we do not use animations.

NavigationWindow dataflow

I am writing my first wpf application now .
I want to use a NavigationWindow on each page the user make selections and all the data should be available on the next pages, I have about 6 page.
How I should path all the data ? via the constructor ? or there is some smarter way in WPF .
On the last page there will be a lot data to path from the previous pages.
I would attack this from one of two ways: The Code-behind way (Easy, but difficult to expand, also will get very messy), and the MVVM way (Takes some learning, separates concerns, easy to extend, manage).
In the code-behind way, I would just have a Tab control with the tab headers styled the way you want them (you can style them to look like just about anything you want). In the code-behind you could have some logic that specifies that X Tab is not enabled or Visible until Y criteria are met.
There is a better way, but it comes with a bit of a learning curve, the MVVM design pattern. You would have 6 Page objects that are really just CLR objects that define the contents of the page (e.g. if it is a questionnaire your page objects would contain question objects and title objects for instance).
You could have a couple of Views, a navigation View, and a page view. The NavigationView would be bound to a NavigationViewModel which would have the logic necessary to change the page. The PageView would be bound to one of 6 PageViewModels and the PageViews DataContext (which provides that binding) could be changed based on the NavigationViews logic.
Learning Prism composite application guidance for WPF Silverlight MVVM Fundamentals
MSDN Page for MVVM explanation
Night Walker,
It is difficult to make out exactly what you want to do from your explanation. First, the NavigationWindow is the frame of your application, I think you know this but I just wanted to make sure we understood that we're not creating new instances of the NavigationWindow. I think you mean 'Pages'. Pages are the content of a Navigation window and represent some target that you want to appear in the ContentPresenter that is provided by the NavigationWindow.
I'm again not sure how you are using the phrase 'Path the data'. Typically you would create Pages either directly in the project or in satellite projects and then reference them using Pack URIs. An example of how Pack URIs are constructed can be found here.
http://msdn.microsoft.com/en-us/library/aa970069(v=vs.85).aspx
You can then navigate to the pack URLs using an expression that looks like:
this.Navigate(new Uri("pack://application:,,,/MyAssembly;component/MyPage.xaml", UriKind.Absolute);
If you don't want to get involved with all the nuts-and-bolts of the framework for navigation and just want to focus on the application for your users, you can check out the professional version of the NavigationControl that I put together:
http://www.teraque.com/products/explorer-chrome-suite/
There's an free demo you can download. If this is was you are looking to do I can give you pointers if you don't want to purchase the package directly.
Sincerely,
Donald Roy Airey
donald.roy.airey#teraque.com

WPF XAML code-behind management

I have wandered into a WPF application project and have made some good progress, but one thing I am finding is that the code-behind page is now getting longer and longer... since there is only one XAML page to the whole application, the code-behind page that really just takes care of the event handlers and programmatically created controls for the design page, is now over 2000 lines. The VS2010 IDE helps in navigating all the methods, etc, but I am wondering if I am missing something as far as organizing all my controls and code-behind. Is there a way to break out some of the UI of the application into multiple XAML pages, so the code-behind will be more compartmentalized to a specific set of controls. Any search I do on multiple XAML file applications in WPF immediately leads me to XBAPS and I am interested in staying with the desktop WPF. Aside from creating regions in the one code-behind, are there any other strategies I can use to organize this code (in separate XAML files)?
Thanks!
At a minimum, separate out parts of your UI into separate UserControls, instead of including it in a single "view" in a single Window.
That being said, separating our your logic and using a pattern like MVVM will make this much cleaner in the long run. It sounds like you're using lots of event handlers - I wrote a blog series designed to help migrate from this style of development to a more MVVM style. It might be worth glancing at for ideas. It describes how WPF allows you to move away from having lots of event handlers by keeping your application logic separated from your UI code.

Silverlight Prism: How to change the shell layout for a new page?

I am new to Silverlight/Prism, so not sure how a new layout page would be rendered. I've got the Shell working like a master page, but I want to have several pages in the application with a different layout master. So, how do I get another (shell) or layout page to arrange different regions?
Thanks for any conceptual feedback!
Have you considered having your Shell view contain either a ContentControl or a ItemsControl so that you can programmatically load different views. These different views could then contain regions or whatever you wanted.
I'd also remember that PRISM is likened to a buffet, you can pick and choose which parts to use. Once you look at ItemsControl and ContentControl consider what regions offer.
Treating Prism regions like Master pages seems to always lead to confusion. It is not designed (like ASP.Net) to potentially render a new shell around every page that appears. That was created for a Browser -> Server -> Browser model where the page is recreated on every request.
To implement a master page style scenario all you are really doing is providing a choice of outer shells that have the same region names defined, but in different visuals or positions. Changing the shell via an element/region in the root visual will cause all the child regions to repopulate in their new homes.
Personally I treat Silverlight more like I would a desktop application and less like a website. I dropped the idea of Master pages (as it feels backwards) and just use dynamic styling for overall changes.
Hope this helps.
The following thread deals with a similar situation. I hope it is useful.
http://compositewpf.codeplex.com/Thread/View.aspx?ThreadId=671911.
Thanks,
Damian.

Resources