Second Stanza

May 2, 2009

Resizing a Silverlight Control within the Browser

Filed under: Silverlight — Tags: — dfbaskin @ 12:27 pm

A common user interface technique in a web page is to expand the contents of the page to the size of the browser window. There are solutions for doing this in both CSS or Javascript. A Silverlight control may also be resized in this way and since a Silverlight control can access the Browser’s DOM (unless permission is explicitly denied), resizing can be handled within the control itself.

To do so, the control will need to be notified of the browser’s OnResize event, which can be attached using the following code:

...
HtmlPage.Window.AttachEvent( "onresize", new EventHandler<HtmlEventArgs>( BrowserWindow_Resized ) );
...

void BrowserWindow_Resized( object sender, HtmlEventArgs e )
{
    AdjustControlSize();
}

Then, you can determine the new size of the browser window using a technique similar to what might be used in Javascript:

        public static bool IsIECSSCompatibleMode
        {
            get
            {
                bool isCompatibleMode = false;
                string mode = HtmlPage.Document.GetProperty( "compatMode" ) as String;
                if( ( mode != null ) && ( String.Compare( mode, 0, "CSS1", 0, 4, StringComparison.InvariantCultureIgnoreCase ) == 0 ) )
                    isCompatibleMode = true;
                return isCompatibleMode;
            }
        }

        public static double BrowserWindowWidth
        {
            get
            {
                object w = HtmlPage.Window.GetProperty( "innerWidth" );
                if( w != null )
                    return Convert.ToDouble( w );
                else if( IsIECSSCompatibleMode )
                {
                    w = HtmlPage.Document.Body.Parent.GetProperty( "clientWidth" );
                    if( w != null )
                        return Convert.ToDouble( w );
                }
                else
                {
                    w = HtmlPage.Document.Body.GetProperty( "clientWidth" );
                    if( w != null )
                        return Convert.ToDouble( w );
                }
                return double.NaN;
            }
        }

        public static double BrowserWindowHeight
        {
            get
            {
                object h = HtmlPage.Window.GetProperty( "innerHeight" );
                if( h != null )
                    return Convert.ToDouble( h );
                else if( IsIECSSCompatibleMode )
                {
                    h = HtmlPage.Document.Body.Parent.GetProperty( "clientHeight" );
                    if( h != null )
                        return Convert.ToDouble( h );
                }
                else
                {
                    h = HtmlPage.Document.Body.GetProperty( "clientHeight" );
                    if( h != null )
                        return Convert.ToDouble( h );
                }
                return double.NaN;
            }
        }

I’ve encapsulated this technique into a Silverlight control called AutoSizeUserControl. This control is derived from the standard UserControl and automatically resizes itself based on changes to the size of the browser window. It can be used simply as a replacment for the UserControl:

<stz:AutoSizeUserControl x:Class="Demo.AutoSizeDemo"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:stz="clr-namespace:Stanza.Silverlight.Controls;assembly=Stanza.Silverlight.Controls" Width="800" Height="600" MinWidth="300" MinHeight="200" ExtraHeight="164" ExtraWidth="20">
    <Grid x:Name="LayoutRoot" Background="White">
		<Rectangle Stroke="#FF000000" RadiusX="16" RadiusY="16" StrokeThickness="4" >
			<Rectangle.Fill>
				<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
					<GradientStop Color="#FF000000"/>
					<GradientStop Color="#FFFFFFFF" Offset="1"/>
				</LinearGradientBrush>
			</Rectangle.Fill>
		</Rectangle>
		<Grid HorizontalAlignment="Center" VerticalAlignment="Center" Width="250" Height="120">
			<Grid.RowDefinitions>
				<RowDefinition/>
				<RowDefinition/>
				<RowDefinition/>
				<RowDefinition/>
			</Grid.RowDefinitions>
			<Grid.ColumnDefinitions>
				<ColumnDefinition/>
				<ColumnDefinition/>
				<ColumnDefinition/>
				<ColumnDefinition/>
			</Grid.ColumnDefinitions>
			
			<TextBlock Text="Browser Window" Grid.Row="0" Grid.Column="0" HorizontalAlignment="Center" VerticalAlignment="Center" Grid.ColumnSpan="2"/>
			<TextBlock Text="Width:" Grid.Row="1" Grid.Column="0" HorizontalAlignment="Center" VerticalAlignment="Center"/>
			<TextBox Text="0" x:Name="browserWidthBox" Grid.Column="1" IsReadOnly="True" Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center" MinWidth="40"/>
			<TextBlock HorizontalAlignment="Center" Text="Height:" Grid.Row="2" Grid.Column="0" VerticalAlignment="Center"/>
			<TextBox Text="0" x:Name="browserHeightBox" Grid.Column="1" Grid.Row="2" IsReadOnly="True" HorizontalAlignment="Center" VerticalAlignment="Center" MinWidth="40"/>
			
			<TextBlock Text="Silverlight Control" Grid.Row="0" Grid.Column="2" HorizontalAlignment="Center" VerticalAlignment="Center" Grid.ColumnSpan="2"/>
			<TextBlock Text="Width:" Grid.Row="1" Grid.Column="2" HorizontalAlignment="Center" VerticalAlignment="Center"/>
			<TextBox Text="0" x:Name="controlWidthBox" Grid.Column="3" IsReadOnly="True" Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center" MinWidth="40"/>
			<TextBlock HorizontalAlignment="Center" Text="Height:" Grid.Row="2" Grid.Column="2" VerticalAlignment="Center"/>
			<TextBox Text="0" x:Name="controlHeightBox" Grid.Column="3" Grid.Row="2" IsReadOnly="True" HorizontalAlignment="Center" VerticalAlignment="Center" MinWidth="40"/>
			
			<Button Grid.Row="3" Content="Full Screen" Grid.ColumnSpan="2" Grid.Column="1" Width="80" Height="24" x:Name="fullScreenButton"/>
			
		</Grid>
    </Grid>
</stz:AutoSizeUserControl>

Source code can be downloaded from CodePlex.

2 Comments »

  1. Its good to see these examples, I was looking for some up-to-date resizing code.

    Unfortunately, the examples only work in Internet explorer. neither Chrome or mozilla firefox… and I haven’t tried opera

    Comment by lexius7 — June 1, 2009 @ 3:45 pm

  2. im using it now and it works great,
    I was a little confused at beginning because my controls didn’t change when resizing,
    I had to change them inside the sizechanged event:

    void root_SizeChanged(object sender, SizeChangedEventArgs e)
    {
    this.DwontimeTree.Height = e.NewSize.Height-50;
    this.DTScheduler.Height = e.NewSize.Height-50;
    }

    thanks!

    Comment by montelof — October 5, 2010 @ 4:22 pm


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Create a free website or blog at WordPress.com.

%d bloggers like this: