AlexMnrs
AlexMnrs

Reputation: 61

How to create a simple menu with labels on the left side with WPF?

I've been developing some simple apps (just for educational purposes) with Windows Forms and now I'm starting to learn WPF, but it seems a bit more complex to me.

I would like to create a simple menu like the one you can see in the pictures. I've been trying to find it on Google and YouTube, but I only found tutorials about "Hamburger menu", which isn't what I'm looking for.

Ultimate Windows Tweaker

Ultimate Windows Tweaker

Ultimate Windows Tweaker

Upvotes: 0

Views: 3317

Answers (1)

Mitch
Mitch

Reputation: 22311

This is really an area where WPF shines: the layout you describe can be implemented with nothing more than a restyled tab control.

Start with an unstyled tab control with TabStripPlacement of Left:

Unstyled tabstrip left

Then edit the TabControl style to add gradient and margins behind the TabPanel:

tabcontrol with unstyled tabitems

Add the image and override the TabItem style to set the font and remove the background. I used a chevron to indicate selection rather than bolding the text, but that would have been handled the same way.

completed TabControl

Here is the full XAML used for the screenshots above:

<Window x:Class="StackOverflowTabControl.MainWindow"
        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:StackOverflowTabControl"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
        <Style x:Key="ItemContainerStyle" TargetType="{x:Type TabItem}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type TabItem}">
                        <Grid Margin="15,5">
                            <Path Width="10" Height="14" Margin="0,2,0,0" HorizontalAlignment="Left" VerticalAlignment="Center" Stretch="Fill" Fill="#FF000000" Data="F1 M 39.8307,37.6042L 36.6641,34.4375L 25.1849,23.3542L 35.4766,23.3542L 50.5182,37.6042L 35.4766,51.8542L 25.1849,51.8542L 36.6641,40.7708L 39.8307,37.6042 Z " Visibility="{Binding IsSelected, Converter={StaticResource BooleanToVisibilityConverter}, RelativeSource={RelativeSource TemplatedParent}}"/>
                            <ContentPresenter Content="{TemplateBinding Header}" Margin="20,5,10,5">
                                <ContentPresenter.Resources>
                                    <Style TargetType="{x:Type TextBlock}">
                                        <Setter Property="FontSize" Value="18" />
                                        <Setter Property="FontWeight" Value="Light" />
                                    </Style>
                                </ContentPresenter.Resources>
                            </ContentPresenter>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
        <Style x:Key="TabControlStyle1" TargetType="{x:Type TabControl}">
            <Setter Property="TabStripPlacement" Value="Left" />
            <Setter Property="ItemContainerStyle" Value="{StaticResource ItemContainerStyle}" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type TabControl}">
                        <Grid x:Name="templateRoot" ClipToBounds="true" SnapsToDevicePixels="true" KeyboardNavigation.TabNavigation="Local">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto" />
                                <ColumnDefinition Width="1*" />
                            </Grid.ColumnDefinitions>
                            <Border Grid.Column="0" Padding="5">
                                <Border.Background>
                                    <LinearGradientBrush EndPoint="0,0" StartPoint="1,0">
                                        <GradientStop Color="#FFC7C7C7" Offset="0"/>
                                        <GradientStop Color="#FFECECEC" Offset="1"/>
                                    </LinearGradientBrush>
                                </Border.Background>
                                <DockPanel>
                                    <Image DockPanel.Dock="Bottom" HorizontalAlignment="Center" Margin="20" Source="pack://application:,,,/StackOverflowTabControl;component/twc.png" Width="200" />
                                    <TabPanel x:Name="headerPanel" Background="Transparent" Grid.Column="0" IsItemsHost="true" Margin="2,2,2,0" Grid.Row="0" KeyboardNavigation.TabIndex="1" Panel.ZIndex="1"/>
                                </DockPanel>
                            </Border>
                            <Border x:Name="contentPanel" Grid.Column="1" Margin="5,0,0,0">
                                <ContentPresenter x:Name="PART_SelectedContentHost" ContentSource="SelectedContent" Margin="{TemplateBinding Padding}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                            </Border>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>
    <Grid>
        <TabControl Style="{DynamicResource TabControlStyle1}">
            <TabItem Header="System Information">
                <TextBlock Text="Windows 10 pro" />
            </TabItem>
            <TabItem Header="Something else">
                <TextBlock Text="Other page" />
            </TabItem>
        </TabControl>
    </Grid>
</Window>

Upvotes: 8

Related Questions