• How-to Hide Views inside Composite Application Guidance (aka Prism-v2) regions.

    Published by on July 2nd, 2009 12:21 pm under Composite Application Guidance, Patterns and Practices, Prism, Prism-v2, Silverlight, WPF

    8 Comments

    The IRegion interface allows to Add/Remove and Activate/Deactivate the views contained in the region. These two sets of actions let us manipulate the state of each view in regions. While the meaning of Add/Remove is clear, the semantics of Activate/Deactivate might be confusing as it greatly depends on the concrete implementation of IRegion.

    Activate semantic by concrete region implementation (between brackets is the type of control attached to by default):

    • SingleActiveRegion (ContentControl): There is a maximum of one active region at a time. This means that activating a view might trigger a deactivation of another view.
      If the region is created with the default adapter (ContentControlRegionAdapter) the active view will also be only one visible, as it is set as the content of the ContentControl.
    • AllActiveRegion (ItemsControl): All views that are kept in the region are active. Calling Deactivate on a view will throw an InvalidOperationException. All views are usually visible.
    • Region (Selector): This region allows for multiple active and deactive views.
      If created with the default adapter (SelectorRegionAdapter) the active views will be kept in sync with the SelectedItem/SelectedItems of the control. So when calling Activate on a view, you can only select a single active view at a time. By setting the SelectedItems property of a listbox, you can set multiple views to active. All views (active and deactive) are visible.

    The RegionActiveAwareBehavior and the IActiveAware interface are very close related to the activate semantic. So for example, even if the IActiveAware interface is implemented in a view, if it is contained in an AllActiveRegion, the view will only be notified of the active state change only once (when added to the region).

    Hiding views

    Activating and deactivating views is usually confused with it’s visibility. If you deactivate a view, it will only hide it if the region is a SingleActiveRegion. It will throw an exception in AllActiveRegions and it will not hide the view in Regions.

    The posibility of hiding views while keeping the view in the region is not implemented out-of-the-box in prism-v2. Hiding view only makes sense in ItemsControl containers, as in other containers views are automatically hidden when they are not active. Hiding views might be particularly helpful, for example if there is a requirement to hide certain TabItems (as deactivating the view won’t hide the tab, and setting Visibility=Hidden in the view won’t hide the tab).

    With Damian Schenkelman, we created the following two classes (one for Silverlight and one for WPF) that add extension methods to allow hide/show views in prism-v2 regions (Download links below). WPF methods implements hide/show for all ItemsControl containers while Silverlight methods are only implemented for the TabControl.

    · SilverlightRegionExtensions (allow hide views in TabControl regions)

    · WPFRegionExtensions (allow hide views in ItemsControl regions)

    The aforementioned classes expose the following extension methods for the IRegion interface:

    · Hide(string viewName): Hides a view registered with a particular name in the region.

    · Hide(object view): Hides the view passed as a parameter.

    · Show(string viewName): Shows a view registered with a particular name in the region.

    · Show(object view): Shows the view passed as a parameter.

    We also created a sample application to show it’s usage and to highlight the difference betwen Add/Remove, Activate/Deactivate, Hide/Show.
    image

    You can play with it selecting the tab checkboxes and pressing the action buttons.

     

    Download

    We uploaded the WPF and silverlight region extension method to the Prism codeplex site. You can get these classes from RegionExtensions.zip.

    You can also downloaded the sample application from Hide Views Sample .
    kick it on DotNetKicks.com

    Tags: , , , , ,

    • James Stewart

      I have decided to see if I can solve my similar problem using these techniques. In the example given, all the views are loaded and shown at startup.

      In my case, I really only want to see one view at starup (in the future, the control may need to contain >1 visible views) – how do I switch off the display of, say, Views 2 and 3?

      Simple code like

      this.regionManager.Regions[“TabRegion”].Hide(“View2″);

      always fails with the exception saying that “TabRegion” is unknown. Clearly it is a question of where, in the event sequence, I put this code. I thought the Window Loaded event would do, but, same problem.

      Any suggestions?

    • James Stewart

      After a bit of slog, I have got something working:

      protected override void InitializeModules()
      {
      base.InitializeModules();
      shell.SetupViewVisibility();
      }
      where SetupViewVisibility() shows/hides what I need at startup. Please confirm if this is a good way to do what I want to do, and also suggest where these timings/event sequence is documented. Thanks!

    • Mike Garrett

      Hide View Sample contains a modified Microsoft.Practices.Composite.Presentation.dll which does not throw an error on “content tab view” (a la explorer’s quick tabs) when a FabTabControl is used as a Region in Shell. Can you provide help reproducing the Microsoft.Practices.Composite.Presentation.dll from source code. Thanks.

    • Mike Garrett

      Found the correct Microsoft.Practices.Composite.Presentation.dll on codeplex in latest release V3. Please disregard prior question.

    • Mike Garrett

      To follow up, for your information,

      compositewpf-26112 V2 Microsoft.Practices.Composite.Presentation.dll using a FabTab region:
      in Regions.cs, GetItemMetadataOrThrow, throw new ArgumentException Resources.ViewNotInRegionException, “view”);

      produces:

      System.ArgumentException was unhandled
      Message=”The region does not contain the specified view. Parameter name: view”
      where view refers to {FabTab.ContentView}

      apparently, compositewpf-26112 V3 attempts to display an new view in a region before throwing an exception so that clicking on the content tab of FabTab allows FabTab to create and display a new view that was not in the region.

    • Mike Garrett

      follow up,

      Only differences in V2 and V3 source directies for Microsoft.Practices.Composite.Presentation.dll (desktop) are in the commands directory yet I cannot seem to identify the change that is creating the result. I will just be content that it is working.

      Thanks.

    • Mike Garrett

      follow up,

      Difference was not in V2 -> V3 but CompositeApplicationGuidance-Feb2009.exe -> compositewpf-26112.zip V2

      between 02/09 and 08/09 selectoritemssourcesyncbehavior.cs was changed, allowing the user to set the selected item to a view that is not in the region.
      Thanks

    • Savvas Sopiadis

      I played around with your app and i liked it!(i’m new to Prism)
      But what if want to load a module (which then loads a view to a tabitem), close this view and want to reopen it again.
      Is this scenario somehow achievable (taking into account that i have to write a MVVM-oriented application)?

      Thanks in advance