Problems with TabControl Region (Silverlight)

Topics: Prism v2 - Silverlight 2
Mar 30, 2009 at 9:28 AM
I am building a composite application which uses a tab control as its main display region. When the user clicks on a menu item, modules are demand loaded and their single views are assigned to the tab control region. This is working fine. I have two problems though.

First, I am having trouble using a theme with the application. If I set the implicit style manager on my layout root (a grid) and reference one of the themes (I'm using BureauBlue, but it doesn't matter which one) and set the apply mode to Auto, I get the theme applied to my Shell and all my module's views as expected, however, I was using the technique of setting TabControlRegionAdapter.ItemContainerStyle to data bind the text of the tab to a string provided in the view model (which is the data context of the views) like so:

    <Style TargetType="basics:TabItem">
        <Setter Property="HeaderTemplate">
                    <TextBlock Text="{Binding HeaderInfo}" />

This "works", except that the BeureaBlue style doesn't get applied to the tab item headers. After a little research, I realized that Silverlight doesn't support merging of styles, so it appears it is an all or nothing affair. So I bound a copy the BureauBlue xaml file as a resource and tried to modify the style in it for TabItems. This style consists of a few simple property setters and then a large ControlTemplate which does all the graphics for the presentation of the themed tab items. I tried adding a HeaderTemplate setter just before the large ControlTemplate which did the data binding, and this also "works"...I get the BureauBlue style tab headers with the header info string, except for this oddity: The views are UserControl's which are designed to fill their container and resize as the container is resized. If I have only one view in the tab control (i.e., one tab) this works fine, however, as soon as there are two or more, changing the selected tab causes the hosted UserControl to shrink to its design size, centered. This is even true of the first loaded tab, which starts out filling the tab and resizing properly, but if I switch to another tab and then back, it too is compressed and centered.

My second problem is also a sizing one. A few of these views can be rather large, and if the browser window (and hence the tab item) are too small, the control is just clipped. I want to be able to have scrollbars appear if the available space for the hosted control is smaller than some size, say 750x500, but I can't get that to work at all either. If I run the user control in its own page, i.e., setting it to RootVisual, I found I could use something like this (leaving out the namespace declarations to save space):

<UserControl Width="Auto" Height="Auto">
    <Grid x:Name="LayoutRoot">
        <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
            <Grid Background="Blue" MinWidth="400" MinHeight="300">

If I make this "view" the main page, I get the desired result: the control (which is just a blue square) fills the browser window, but if it is resized to where the inner grid would be smaller than 400x300, scroll bars appear. However, if I register this "view" to the tab control, the blue grid fills the tab item, but if it is resized to less than 400x300, no scroll bars appear and the grid is simply clipped. Of course, in my real case, this grid has a complex UI of buttons, combo boxes, text boxes, labels, etc.

Sorry for the long-winded explanation. I admit I am new to Silverlight, and so maybe I am making some stupid mistakes, but I am stumped with these two issues. In the end, I can give up on the theme if I have to, and just use the default, thought I really like the BureauBlue theme better. The second issue, though, seems like it would be a fairly common one: You define a view which requires a certain amount of screen space to work properly, and you want to deal with a situation where the user either makes the browser too small or perhaps even is using a monitor with a small screen, and so you want to scroll the view instead of just mashing it to the point of unusability or clipping it. I have to believe there is a way to deal with this. I suppose I could re-design the large views into multiple pages, but I really don't like making hard-coded assumptions about how mush screen space I have.

Any advice greatly appreciated.

Apr 2, 2009 at 9:58 PM
Hi Dave,

I take it you're not a web development expert either (or if you are, these things happen anyway). I'd been looking for a solution to your sizing problem for days as I was having the same issue. Hopefully, what I found will also help you... in the HTML page that hosts your Silverlight control should exist the following code (or similar):

    <div id="silverlightControlHost">
<object data="data:application/x-silverlight-2," type="application/x-silverlight-2">

Add the fixed width and height that are definied in your control to be the same for the object that contains it, like so:

    <div id="silverlightControlHost">
<object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="400px" height="300px">

This should let the browser know that the object in that position is of the size 400x300 and if the window shrinks below that, that it should show the scroll bars to compensate.

Hope this helps!

Jun 3, 2009 at 6:57 AM

You may already know this but I just tried to use the new  Silverlight 3 option to override the style using the attribute: BasedOn and it is working for me. Not sure if this helps in your example.

<font size="2" color="#a31515"><font size="2" color="#a31515">


</font></font><font size="2" color="#a31515">



<Style TargetType="controls:TabItem" BasedOn="{StaticResource TabItemStandardStyle}">

Have a great day.