Home > Software engineering >  How to make some part of WPF design common to multiple windows
How to make some part of WPF design common to multiple windows

Time:11-25

so I'm making this Visual Basic WPF and I have a navigation bar that will be common between multiple windows and I was wondering if there is a way to make a XAML and class only for this navigation bar and then import it to other windows so I don't have to copy and paste the same code every time I create a new window.

The current code:

MainWindow.vb

Class FloorWindow
    Private Sub SetAllInactive()
        ' This function will change all StackPanel objects
        ' of the navGrid to its inactive style which consists
        ' of opacity .1

        Dim childType As String

        For Each child In navGrid.Children
            childType = child.GetType().ToString()
            ' Check if child object of navGrid is a StackPanel
            If childType = "System.Windows.Controls.StackPanel" Then
                child.Opacity = 0.1
            End If
        Next
    End Sub
    Private Sub LogoBtnClick(sender As Object, e As RoutedEventArgs) Handles logoBtn.Click
        Trace.WriteLine("Logo Clicked")
        ' Go to default page
        SetAllInactive()
        floorStack.Opacity = 1
    End Sub

    Private Sub FloorBtnClick(sender As Object, e As RoutedEventArgs) Handles floorBtn.Click
        Trace.WriteLine("Floor Clicked")
        ' Go to floor page and change its stack to active attributes
        SetAllInactive()
        floorStack.Opacity = 1
    End Sub

    Private Sub ClientsBtnClick(sender As Object, e As RoutedEventArgs) Handles clientsBtn.Click
        Trace.WriteLine("Clients Clicked")
        ' Go to floor page and change its stack to active attributes
        SetAllInactive()
        clientsStack.Opacity = 1
    End Sub

    Private Sub SettingsBtnClick(sender As Object, e As RoutedEventArgs) Handles settingsBtn.Click
        Trace.WriteLine("Settings Clicked")
        ' Go to floor page and change its stack to active attributes
        SetAllInactive()
        settingsStack.Opacity = 1
    End Sub
End Class

MainWindow.xaml

<Window x:Class="FloorWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:RestaurantManager"
        xmlns:fa5="http://schemas.fontawesome.com/icons/"
        mc:Ignorable="d"
        Title="Restaurant Floor" Height="450" Width="800">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="70"/>
            <ColumnDefinition Width="1*"/>
        </Grid.ColumnDefinitions>
        <Grid x:Name="navGrid" Background=" #212121">
            <Grid.RowDefinitions>
                <!-- Height of item menu should be same as width of the outter column -->
                <RowDefinition Height="70"/>
                <RowDefinition Height="70"/>
                <RowDefinition Height="70"/>
                <RowDefinition Height="70"/>
            </Grid.RowDefinitions>
            <!-- Menu Item Defenition Start -->
            <Border Grid.Row="0" BorderBrush="White" BorderThickness="0 0 0 .1"/>
            <Button x:Name="logoBtn" Grid.Row="0" Panel.ZIndex="10" TabIndex="10" Opacity="0"/>
            <TextBlock Grid.Row="0" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="40" Foreground="#03DAC5">
                E
            </TextBlock>
            <Border Grid.Row="1" BorderBrush="White" BorderThickness="0 0 0 .1"/>
            <Button x:Name="floorBtn" Grid.Row="1" Panel.ZIndex="10" TabIndex="10" Opacity="0"/>
            <StackPanel x:Name="floorStack" Grid.Row="1" VerticalAlignment="Center" HorizontalAlignment="Center">
                <fa5:SvgAwesome Icon="Solid_BorderAll" Width="20" Foreground="White"/>
                <TextBlock Foreground="White" HorizontalAlignment="Center" Margin="0,5,0,0">Floor</TextBlock>
            </StackPanel>
            <Border Grid.Row="2" BorderBrush="White" BorderThickness="0 0 0 .1"/>
            <Button x:Name="clientsBtn" Grid.Row="2" Panel.ZIndex="10" TabIndex="10" Opacity="0"/>
            <StackPanel x:Name="clientsStack" Grid.Row="2" VerticalAlignment="Center" HorizontalAlignment="Center" Opacity=".1">
                <fa5:SvgAwesome Icon="Solid_UserFriends" Width="20" Foreground="White"/>
                <TextBlock Foreground="White" HorizontalAlignment="Center" Margin="0,5,0,0">Clients</TextBlock>
            </StackPanel>
            <Border Grid.Row="3" BorderBrush="White" BorderThickness="0 0 0 .1"/>
            <Button x:Name="settingsBtn" Grid.Row="3" Panel.ZIndex="10" TabIndex="10" Opacity="0"/>
            <StackPanel x:Name="settingsStack" Grid.Row="3" VerticalAlignment="Center" HorizontalAlignment="Center" Opacity=".1">
                <fa5:SvgAwesome Icon="Solid_Cogs" Width="20" Foreground="White"/>
                <TextBlock Foreground="White" HorizontalAlignment="Center" Margin="0,5,0,0">Settings</TextBlock>
            </StackPanel>
            <!-- Menu Item Defenition End -->
        </Grid>
    </Grid>
</Window>

CodePudding user response:

  1. Create a new UserControl (Project->Add User Control (WPF) in Visual Studio)

  2. Move the "navGrid" element to be reused (cut and paste) from the MainWindow to the XAML markup of the newly created UserControl.

    The XAML markup of the UserControl should the look something like this:

     <UserControl ...
             xmlns:local="clr-namespace:RestaurantManager"
             xmlns:fa5="http://schemas.fontawesome.com/icons/">
         <Grid>
             <Grid.ColumnDefinitions>
                 <ColumnDefinition Width="70"/>
                 <ColumnDefinition Width="1*"/>
             </Grid.ColumnDefinitions>
             <Grid x:Name="navGrid" Background=" #212121">
                 <Grid.RowDefinitions>
                     <!-- Height of item menu should be same as width of the outter column -->
                     <RowDefinition Height="70"/>
                     <RowDefinition Height="70"/>
                     <RowDefinition Height="70"/>
                     <RowDefinition Height="70"/>
                 </Grid.RowDefinitions>
                 <!-- Menu Item Defenition Start -->
                 <Border Grid.Row="0" BorderBrush="White" BorderThickness="0 0 0 .1"/>
                 <Button x:Name="logoBtn" Grid.Row="0" Panel.ZIndex="10" TabIndex="10" Opacity="0"/>
                 <TextBlock Grid.Row="0" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="40" Foreground="#03DAC5">
                     E
                 </TextBlock>
                 <Border Grid.Row="1" BorderBrush="White" BorderThickness="0 0 0 .1"/>
                 <Button x:Name="floorBtn" Grid.Row="1" Panel.ZIndex="10" TabIndex="10" Opacity="0"/>
                 <StackPanel x:Name="floorStack" Grid.Row="1" VerticalAlignment="Center" HorizontalAlignment="Center">
                     <fa5:SvgAwesome Icon="Solid_BorderAll" Width="20" Foreground="White"/>
                     <TextBlock Foreground="White" HorizontalAlignment="Center" Margin="0,5,0,0">Floor</TextBlock>
                 </StackPanel>
                 <Border Grid.Row="2" BorderBrush="White" BorderThickness="0 0 0 .1"/>
                 <Button x:Name="clientsBtn" Grid.Row="2" Panel.ZIndex="10" TabIndex="10" Opacity="0"/>
                 <StackPanel x:Name="clientsStack" Grid.Row="2" VerticalAlignment="Center" HorizontalAlignment="Center" Opacity=".1">
                     <fa5:SvgAwesome Icon="Solid_UserFriends" Width="20" Foreground="White"/>
                     <TextBlock Foreground="White" HorizontalAlignment="Center" Margin="0,5,0,0">Clients</TextBlock>
                 </StackPanel>
                 <Border Grid.Row="3" BorderBrush="White" BorderThickness="0 0 0 .1"/>
                 <Button x:Name="settingsBtn" Grid.Row="3" Panel.ZIndex="10" TabIndex="10" Opacity="0"/>
                 <StackPanel x:Name="settingsStack" Grid.Row="3" VerticalAlignment="Center" HorizontalAlignment="Center" Opacity=".1">
                     <fa5:SvgAwesome Icon="Solid_Cogs" Width="20" Foreground="White"/>
                     <TextBlock Foreground="White" HorizontalAlignment="Center" Margin="0,5,0,0">Settings</TextBlock>
                 </StackPanel>
                 <!-- Menu Item Defenition End -->
             </Grid>
         </Grid>
     </UserControl>
    
  3. Move any code (cut and paste) that is related to the navigation elements from the code-behind of the window to the code-behind of the UserControl

  4. Add the UserControl to any window where you want to your common navigation bar:

     <Window x:Class="FloorWindow"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:local="clr-namespace:RestaurantManager"
             xmlns:fa5="http://schemas.fontawesome.com/icons/"
             mc:Ignorable="d"
             Title="Restaurant Floor" Height="450" Width="800">
         <Grid>
             <Grid.ColumnDefinitions>
                 <ColumnDefinition Width="70"/>
                 <ColumnDefinition Width="1*"/>
             </Grid.ColumnDefinitions>
             <local:UserControl1 />
             ...
         </Grid>
     </Window>
    
  • Related