Collapsible Menu in WPF

Collapsible menu

Collapsible menu in WPF is a menu which can be expend or collapse by clicking a button. They are very useful when we want to short a content of a long page. Expandable menus are not useful if it hides content of page in expended state.

In this tutorial we’ll learn how to design a collapsible menu in WPF C#.

Tools Required:

  1. Visual Studio 2010 or later version.
  2. Pichon App for icons (Optional). Download it from HERE.

Steps to Follow:

  1. Open Visual Studio and create a new WPF Application Project.
  2. Open the XAML file of your Main Window.
  3. select the Form, go to properties and Change Windows Style property to None. Resize Mode property to NoResize and window startup location to CenterScreen.
  4. Our layout will contain two main Grids. One for top panel and other for left.

5. Our Top panel will contain a TextBlock.

<Grid x:Name="panelHeader" VerticalAlignment="Top" Height="50" Background="#FF0F4E7A" MouseDown="PanelHeader_MouseDown">

            <TextBlock Text="C# Ui Academy" HorizontalAlignment="Center" VerticalAlignment="Center" FontFamily="Century Gothic" FontSize="20" FontWeight="Bold" Foreground="White"/>

        </Grid>

6. Left panel contains our menu in which we will create buttons to navigate through out our software.

<Grid x:Name="sidePanel" Background="#FF0F4E7A" HorizontalAlignment="Left" Width="150">
            <StackPanel>
                <Grid Height="150" Background="White">
                    <Button HorizontalAlignment="Right" Height="20" VerticalAlignment="Top" Background="Transparent" BorderBrush="Transparent" Click="Button_Click">
                        <Image Source="icons/menu.png"/>
                    </Button>
                </Grid>
                <ListView ScrollViewer.HorizontalScrollBarVisibility="Disabled" FontFamily="Century Gothic" FontSize="14" Foreground="White" BorderBrush="Transparent" Background="Transparent" FontWeight="Bold">
                    <ListViewItem Height="30">
                        <StackPanel Orientation="Horizontal">
                            <Image Source="icons/home.png" Height="20" VerticalAlignment="Center"/>
                            <TextBlock Margin="15 0 0 0" Text="Home" VerticalAlignment="Center"/>
                        </StackPanel>
                    </ListViewItem>
                    <ListViewItem Height="30">
                        <StackPanel Orientation="Horizontal">
                            <Image Source="icons/msg.png" Height="20" VerticalAlignment="Center"/>
                            <TextBlock Margin="15 0 0 0" Text="Inbox" VerticalAlignment="Center"/>
                        </StackPanel>
                    </ListViewItem>
                    <ListViewItem Height="30">
                        <StackPanel Orientation="Horizontal">
                            <Image Source="icons/sent.png" Height="20" VerticalAlignment="Center"/>
                            <TextBlock Margin="15 0 0 0" Text="Sent Items" VerticalAlignment="Center"/>
                        </StackPanel>
                    </ListViewItem>
                    <ListViewItem Height="30">
                        <StackPanel Orientation="Horizontal">
                            <Image Source="icons/spam.png" Height="20" VerticalAlignment="Center"/>
                            <TextBlock Margin="15 0 0 0" Text="Spam" VerticalAlignment="Center"/>
                        </StackPanel>
                    </ListViewItem>
                    <ListViewItem Height="30">
                        <StackPanel Orientation="Horizontal">
                            <Image Source="icons/setting.png" Height="20" VerticalAlignment="Center"/>
                            <TextBlock Margin="15 0 0 0" Text="Settings" VerticalAlignment="Center"/>
                        </StackPanel>
                    </ListViewItem>
                </ListView>
            </StackPanel>
        </Grid>

In this Grid, We have a Stack Panel as a container in which We’ve placed a Grid and ListView inside this Stack Panel. The Grid will contain a button to collapse and expand the SidePanel. And ListView contains the links to other modules of application.

ListViewItems contains an Image for icon and a TextBlock for the Text of button.

XAML Code:

<Window x:Class="WPFDemo.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:WPFDemo"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800" ResizeMode="NoResize" WindowStartupLocation="CenterScreen" WindowStyle="None">
    <Grid Background="#FFD6D6D6">
        <Grid x:Name="panelHeader" VerticalAlignment="Top" Height="50" Background="#FF0F4E7A" MouseDown="PanelHeader_MouseDown">
            <TextBlock Text="C# Ui Academy" HorizontalAlignment="Center" VerticalAlignment="Center" FontFamily="Century Gothic" FontSize="20" FontWeight="Bold" Foreground="White"/>
        </Grid>
        <Grid x:Name="sidePanel" Background="#FF0F4E7A" HorizontalAlignment="Left" Width="150">
            <StackPanel>
                <Grid Height="150" Background="White">
                    <Button HorizontalAlignment="Right" Height="20" VerticalAlignment="Top" Background="Transparent" BorderBrush="Transparent" Click="Button_Click">
                        <Image Source="icons/menu.png"/>
                    </Button>
                </Grid>
                <ListView ScrollViewer.HorizontalScrollBarVisibility="Disabled" FontFamily="Century Gothic" FontSize="14" Foreground="White" BorderBrush="Transparent" Background="Transparent" FontWeight="Bold">
                    <ListViewItem Height="30">
                        <StackPanel Orientation="Horizontal">
                            <Image Source="icons/home.png" Height="20" VerticalAlignment="Center"/>
                            <TextBlock Margin="15 0 0 0" Text="Home" VerticalAlignment="Center"/>
                        </StackPanel>
                    </ListViewItem>
                    <ListViewItem Height="30">
                        <StackPanel Orientation="Horizontal">
                            <Image Source="icons/msg.png" Height="20" VerticalAlignment="Center"/>
                            <TextBlock Margin="15 0 0 0" Text="Inbox" VerticalAlignment="Center"/>
                        </StackPanel>
                    </ListViewItem>
                    <ListViewItem Height="30">
                        <StackPanel Orientation="Horizontal">
                            <Image Source="icons/sent.png" Height="20" VerticalAlignment="Center"/>
                            <TextBlock Margin="15 0 0 0" Text="Sent Items" VerticalAlignment="Center"/>
                        </StackPanel>
                    </ListViewItem>
                    <ListViewItem Height="30">
                        <StackPanel Orientation="Horizontal">
                            <Image Source="icons/spam.png" Height="20" VerticalAlignment="Center"/>
                            <TextBlock Margin="15 0 0 0" Text="Spam" VerticalAlignment="Center"/>
                        </StackPanel>
                    </ListViewItem>
                    <ListViewItem Height="30">
                        <StackPanel Orientation="Horizontal">
                            <Image Source="icons/setting.png" Height="20" VerticalAlignment="Center"/>
                            <TextBlock Margin="15 0 0 0" Text="Settings" VerticalAlignment="Center"/>
                        </StackPanel>
                    </ListViewItem>
                </ListView>
            </StackPanel>
        </Grid>
    </Grid>
</Window>

We’ll use Dispatch Timer which is a class of namespace System.Windows.Threading for smooth collapse and expansion of Grid.

C# Code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;

namespace WPFDemo
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        DispatcherTimer timer;

        double panelWidth;
        bool hidden;
        public MainWindow()
        {
            InitializeComponent();
            timer = new DispatcherTimer();
            timer.Interval = new TimeSpan(0, 0, 0, 0, 10);
            timer.Tick += Timer_Tick;

            panelWidth = sidePanel.Width;
        }

        private void Timer_Tick(object sender, EventArgs e)
        {
            if (hidden)
            {
                sidePanel.Width += 1;
                if (sidePanel.Width >= panelWidth)
                {
                    timer.Stop();
                    hidden = false;
                }
            }
            else
            {
                sidePanel.Width -= 1;
                if (sidePanel.Width <= 35)
                {
                    timer.Stop();
                    hidden = true;
                }
            }
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            timer.Start();
        }

        private void PanelHeader_MouseDown(object sender, MouseButtonEventArgs e)
        {
            if (e.LeftButton == MouseButtonState.Pressed)
            {
                DragMove();
            }
        }
    }
}

On Mouse down event of HeaderPanel we’ve used DragMove(); method which will make our form drag-able even if it do not have a border.

Video Tutorial:

Watch full video tutorial to better understanding.

Source Code:

I hope you enjoyed this Tutorial. Please don’t to subscribe official YouTube Channel of C# Ui Academy

2 comments

  1. There are some intriguing points on time here but I don’t determine if every one of them center to heart. There may be some validity but I am going to take hold opinion until I look into it further. Great article , thanks and now we want much more! Included in FeedBurner at the same time

  2. You really should take part in a contest first of the most useful blogs over the internet. I am going to recommend this website!

Comments are closed.