Too many regions in my shell

Topics: Prism v2 - Silverlight 2, Prism v2 - Silverlight 3
Aug 27, 2009 at 2:40 PM

Hey,

I'm still a bit of a novice on this and I'm working on my first Silverlight application that uses the composite WPF and Silverlight framework.

The situation I've run into is this, I have a login screen that looks totally different than the rest of my application. Different logo's, background colour, totally different layout. So how do I solve this with only one shell? Do I just change the design of the shell dynamically when I load in the usercontrols when a user logs in, or do I put the layout of the entire page in a Module? That would mean I'd need an area that covers the whole page and other area's overlapping this and that doesn't seem like best practise.  How is this generally solved? I can imagine that my application might have multiple different layouts, am I supposed to put all area's for all parts of the application in one shell? Won't that get very messy?

Anyway I hope you get my point and I'm sure there's a good solution for this, I just have to find it. Thanks for any feedback you can give me and if there's anything that I didnt make clear enough please feel free to ask.

Aug 27, 2009 at 6:32 PM

Hi

It is great that you are trying out Prism! Regarding your question, one possible approach could be having this login screen as a view in a particular module. At runtime, you add this view to the MainRegion of your application (before adding any other view). The user logs in, and based on his credentials, you can load the different modules you require on demand (which is useful, because you might avoid downloading unnecessary modules if a particular user does not have some functionality enabled).

Once the rest of the modules are loaded, you can simply replace the View in the MainRegion, which the main view of your application. This is easily achievable using a SingleActiveRegion (attach the region to any ContentControl or inherited control). This kind of region only shows one view at a time. After the different modules are loaded you can show the views you require in other regions you created.

The following articles from the Prism documentation might be useful for you:

Please let me know if this helps.

Damian Schenkelman
http://blogs.southworks.net/dschenkelman

Aug 28, 2009 at 7:28 AM
Edited Aug 28, 2009 at 7:29 AM

Hey,

thanks for the response. Those links are interresting but I don't know if it totally covers my question. I got far enough with Prism to know how to inject views and that but I was wondering about what happens when you add too many regions to the application.

Lets say my main application has a pretty simple layout and has two regions, a main region and a navigation region. so it'd kinda look like this:
____________
|   |          |
|   |          |
|   |          |
|   |          |

Yeah, pretty simple.

So now I want my login screen, this looks pretty different. I want 1 region in the middle. So should I make a new region for that in the shell page? It would kind of overlap the 2 regions I already have, that's not very nice I think. I guess I could use the main region and try and style it in the middle of the page while it is in that but that'd be a bit of a hassle and it would, I think, defeat the point of regions.

So yeah, I know how to add views to regions, but I don't know I can solve the different layouts of regions. What if I want to have one screen in my application that has 6 regions showing some sort of overview. I can't imagine that when using prism you are bound to one layout throughout the entire application. Also the issue about the page layout. Right now I've set my background to gray for the login, but for the main page I want it to be another colour, do I just change this in the code?

Anyway I'll read through those links and see if I can find an answer myself, but if I could get any pointers towards the correct solution it'd be great.

Thanks for your time.

Aug 28, 2009 at 7:37 AM

Remember that you can nest regions. So you can have one region being the entire window contents and two regions as "main region" and "navigation region" for a total of three.

Aug 28, 2009 at 7:50 AM

Hm that doesn't seem like a bad solution, I guess it would solve my login screen issue. But what if I have 4 regions evenly spaced out in part of my application? I guess they could be nested too if I do it properly. I will give it a try, thanks.

May 17, 2010 at 1:16 PM

Tom7, im pulling my hair out for the same reason. I am building a Rich client application but i think i can post here since i am following the Prism frame work and my concern is the same. I have around 6 diffrent screens with diffrent layouts in my application. The Stock Trader Reference Implementation show just one screen and so is neatly divided into some 4 regions. As Tom asks am i bound to one layout if i use prism or is there a nice way. NICE since i want to follow the best practice in this regard and still use the Prism framework. Hope this forum thread has not gone cold and someone would reply. By the way how did u fix it Tom?

May 17, 2010 at 2:39 PM
Edited May 17, 2010 at 2:41 PM

Hey Mike,

Ah this is from a pretty long time ago. Luckily our team did manage to find a solution eventually. I'm not 100% sure if it's the best solution but it works fine for us. Here's what I did basically.

Basically, our application has only 2 really different layouts. The login, which has one screen in the middle and the main application, which has an outlookbar on the left and other screens on the right.

First I made a fullscreen region in the shell.xaml. This is the only region in the shell.
like this:
<ContentControl regions:RegionManager.RegionName="FullScreen"
                        VerticalContentAlignment="Stretch"
                        HorizontalContentAlignment="Stretch">
</ContentControl>

When the application starts I register the Welcome view with the fullscreen region:

  m_regionManager.RegisterViewWithRegion(Regions.FullScreen.ToString(), () => m_container.Resolve<ViewWelcome>());

The ViewWelcome has it's own regions for the login screen. (A little screen in the middle, maybe some other stuff like a newsfeed).

Then when the user has logged in successfully I deactivate the welcome screen and activate the Main screen, which contains all the regions for the main application. I do this in the shell.xaml.cs codebehind, subscribing to an event using the eventaggregator like this in the constructor:

m_eventAggregator.GetEvent<SwitchViewsEvent>().Subscribe(switchViewsEventHandler, true);

And this is the method that it uses to switch the views:

  private void switchViewsEventHandler(string viewSetName)
        {
            switch (viewSetName.ToLower())
            {
                case "login":
                    RegionViewManager.DeactivateView(m_regionManager.Regions[Regions.FullScreen.ToString()],
                        typeof(ViewMain));
                    RegionViewManager.AddAndActivateView(m_regionManager.Regions[Regions.FullScreen.ToString()],
                        typeof(ViewWelcome),
                        m_container);
                    
                    break;
                case "main":
                    RegionViewManager.DeactivateView(m_regionManager.Regions[Regions.FullScreen.ToString()],
                        typeof(ViewWelcome));
                    RegionViewManager.AddAndActivateView(m_regionManager.Regions[Regions.FullScreen.ToString()],
                        typeof(ViewMain),
                        m_container);
                    break;
            }
        }

 

The most interresting classes would be the deactivate and activate methods in the RegionViewManager class, so I'll paste them here.

public static class RegionViewManager
    {
        public static void DeactivateView(IRegion region, Type viewType)
        {
            foreach (object view in region.Views)
            {
                if (view.GetType() == viewType)
                {
                    region.Deactivate(view);
                }
            }
        }
        public static void AddAndActivateView(IRegion region, Type viewType, IUnityContainer container)
        {
            bool found = false;

            foreach (var existingView in region.Views)
            {
                if(existingView.GetType() == viewType)
                {
                    region.Activate(existingView);
                    found = true;
                    break;
                }
            }

            if (!found)
            {
                var view = container.Resolve(viewType);
                region.Add(view);
                region.Activate(view);
            }
        }
    }

 

 

So basically to summarise I first activate the welcome view, which is in the fullscreen Region, then when I login I deactivate the welcome view and activate the main view, also in the fullscreen region. These views both have their own regions which makes it possible for me to basically make as many different layouts in the applications as I want.

I hope this helps, if you still have trouble I could always whip up a little sample application for you when I get home from work.

 

 

 

 

May 17, 2010 at 2:40 PM

Hi Mike,

Although I don’t know the specific of your application, I will try to provide some ideas to achieve your scenario. Let’s assume that instead of 6, you have 2 different layouts (this is still valid for 6, but requires more examples). They could be something like:

You might be inclined to place all of these regions in the Shell and work really hard to get them to display as you need in different moments. However, this is no necessarily the best approach. Another possible way could be having a LayoutModule (or something similar) which provides LayoutViews. Each of the above layouts I took as an example could be views with nested regions and your Shell would only have a single LayoutRegion which occupies the whole window.

With the above mentioned approach you simply change the active layout view to modify the layout of your application. Plus, if you have some common display in all layouts (say a menu at the top), you can make it part of the Shell and simply change all the rest.

I hope the ideas explained above are clear.

Please let me know if this helps.

Damian Schenkelman
http://blogs.southworks.net/dschenkelman

May 17, 2010 at 2:44 PM
Edited May 17, 2010 at 2:44 PM

Damian,

We did consider doing that, but it basically meant we had to put all the views into the shell.xaml, which we didn't like as it totally messed up our design view for the general application in Visual Studio and Blend and it just feels pretty messy. Still it's an interesting approach, I wouldn't mind getting some feedback on what you think of the approach we used (as described in my post above yours).

Developer
Jun 25, 2010 at 8:34 PM

Hi,

Sorry for the delayed response. Your approach seems right, but you could put the logic for activating and deactivating views in a ShellViewModel, instead of the Shell’s code behind. This would give you some benefits, for example testability. You can read more about MVVM in this article.

Another consideration is that, since you are only deactivating the views and not actually removing them, they are still loaded, and so they consume memory, which could be a performance issue.

I hope you find this helpful.

Guido Leandro Maliandi
http://blogs.southworks.net/gmaliandi

Jun 27, 2010 at 5:13 PM

Oh My God,

First of all haaaaaats offfffffff to all you awwwwwwwwwsome guys. Something that was left back in August 2009

was brought back to life in May 2010, and with such dedication.

Thankyou Tom, Thankyou Damian, Thankyou Maliandi and  Thankyou Tom and Thankyou Damian again.

After that 'request of help' of mine, something went wrong, the one person i am alive for today, was facing a deep distress, that is priority-one for me and

so all coding took the backseat.

Its now that i am coming back to this and i cant but thankyou guys again and again. I am going to try out the suggestions and get back with how it worked

in my specific case (with more details of my specific case) and hopefully give you guys back something for all what you all have given here.

Moderator sorry i do not intend to move off the topic, or be unprofessional.

So next post... all technical...

Thanks to all of you.

Jul 1, 2010 at 6:00 AM

Hi Damian,

 

I am trying to build an App similar to what has been mentioned by OP. If I go with the approach that you mentioned where there is a LayoutRegion in Shell which displays my LayoutView. Can you show an example where LayoutView would contain nested regions? Will it be possible to display a UserControl in different LayoutView nested regions? In my design I need to display modal dialogs that appear as overlays. How can I accomplish that?

 

Thanks