Silverlight Master Page
Since I'm old school and so are most of my users, I wanted to create a simple Silverlight app that had a title bar across the top, nav menu on the left side and a content area on the right. You can modify this for mutiple zones and do some pretty slick stuff. Note: This is Silverlight 2 Beta 2 and VS 2008.
The key is to create a Canvas that gets changed when you want to make changes. Here's the code for the above -- notice the Canvas named ContentHolder.
<UserControl x:Class="SilverLightMasterPageTest.Page" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:SilverLightMasterPageTest"> <Grid x:Name="LayoutRoot" Background="#FF5C7590"> <Grid.RowDefinitions> <RowDefinition Height="30" /> <RowDefinition Height="*" /> </Grid.RowDefinitions> <Border Grid.Row="0" CornerRadius="10" Background="#FFDEDEDE" Margin="2,2,2,2" Padding="10,2,10,2"> <TextBlock Text="Master Page Test" VerticalAlignment="Center" Foreground="#FF14517B" /> </Border> <Grid Grid.Row="1"> <Grid.ColumnDefinitions> <ColumnDefinition Width="110" /> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <local:NavBar Grid.Column="0" /> <!-- This canvas is what we change --> <Canvas x:Name="ContentHolder" Grid.Column="1"> <local:Page1 /> </Canvas> </Grid> </Grid> </UserControl>
We need to use a Canvas because it has the Children property that allows us to add / remove child controls. This code shows how to use the Children property to change the page.
Partial Public Class Page Inherits UserControl Public Sub New() InitializeComponent() End Sub Public Sub ChangePage(ByVal newPage As UserControl) ' Removes the currently displayed page ' (including from memory) Me.ContentHolder.Children.RemoveAt(0) ' Adds our new page Me.ContentHolder.Children.Add(newPage) End Sub End Class
The Remove option gets rid of the currently displayed control while Add shows the new control. Now all we need to do is have our navigation bar create the correct control and call ChangePage. This is encapsulated in PagePicker (in the code behind for NavBar).
' Encapsulate the logic to select ' the page to display Private Sub PagePicker(ByVal pageId As PageIds) ' Make sure this goes to the top page so that you can get ' to your change method. ' We're nested in two grids at this point so we need ' to go back up the tree. Dim pg As Page = CType(CType(Me.Parent, Grid).Parent, Grid).Parent Dim newPage As UserControl = Nothing Select Case pageId Case PageIds.Page1 newPage = New Page1 Case PageIds.Page2 newPage = New Page2 Case PageIds.Page3 newPage = New Page3 Case PageIds.Page4 newPage = New Page4 End Select ' This is where the actual change ' occurs. pg.ChangePage(newPage) End Sub Private Sub Page1Button_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) PagePicker(PageIds.Page1) End Sub Private Sub Page2Button_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) PagePicker(PageIds.Page2) End Sub Private Sub Page3Button_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) PagePicker(PageIds.Page3) End Sub Private Sub Page4Button_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) PagePicker(PageIds.Page4) End Sub ' Just makes it easy to identify ' our pages Private Enum PageIds Page1 Page2 Page3 Page4 End Enum
Notice that PagePicker has to get a reference to the top control so that it can call ChangePage. This will probably be one of the things that bites you as you change the layout. Here's the XAML for NavBar and one of the pages.
<UserControl x:Class="SilverLightMasterPageTest.NavBar" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" > <Border CornerRadius="10" Background="#FFDEDEDE" Width="110" Padding="4,4,4,4"> <StackPanel> <Button x:Name="Page1Button" Content="Page 1" Foreground="#FF14517B" BorderThickness="0" BorderBrush="#FFDEDEDE" Click="Page1Button_Click" /> <Button x:Name="Page2Button" Content="Page 2" Foreground="#FF14517B" BorderThickness="0" BorderBrush="#FFDEDEDE" Click="Page2Button_Click" /> <Button x:Name="Page3Button" Content="Page 3" Foreground="#FF14517B" BorderThickness="0" BorderBrush="#FFDEDEDE" Click="Page3Button_Click" /> <Button x:Name="Page4Button" Content="Page 4" Foreground="#FF14517B" BorderThickness="0" BorderBrush="#FFDEDEDE" Click="Page4Button_Click" /> </StackPanel> </Border> </UserControl>
<UserControl x:Class="SilverLightMasterPageTest.Page1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="400" Height="300"> <Grid x:Name="LayoutRoot"> <Border CornerRadius="10" Background="AliceBlue" Width="300" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="10,10,10,10" Padding="5" > <TextBlock Text="This is page 1" FontSize="22" /> </Border> </Grid> </UserControl>
Comments
"Cannot implicitly convert type 'System.Windows.DependencyObject' to 'LibraryMan.Page'. An explicit conversion exists (are you missing a cast?).
Please suggest me.. pls pls......