C# + XAML = Hamburger Menu. Part 2
Перша частина тут. Якщо ви це читаєте, значить приступаємо до наповнення сторінки контентом.
Нижче від <RelativePanel>
у нас знаходиться <SplitView>
.
<SplitView>
грає роль контейнера з двома вікнами. В<SplitView.Pane>
поміщається навігаційне меню, яке зазвичай приховане або не повністю відображається. Її вміст може ставати видимим або ховатись в залежності від властивостей, які задамо.<SplitView.Content>
містить весь контент сторінки (вибачте за каламбур).
Ми розбили сторінку на дві стрічки. У верхній – кнопки «Меню», «Назад» і панель пошуку. В нижній будуть розташовані пункти меню. Якщо не вказано стрічку, в якій буде знаходитись елемент – він розміщується в першій за замовчуванням. Нумерація починається з «0», варто мати це на увазі. <RelativePanel>
автоматично помістилась у першу за порядком і нульову за номером стрічку.
Наш SplitView поміщаємо в другу стрічку, тому задаємо прикріплену властивість (attached property) Grid.Row="1"
Код такий:
<SplitView Grid.Row="1">
<SplitView.Pane>
</SplitView.Pane>
<SplitView.Content>
</SplitView.Content>
</SplitView>
Щоб зразу наповнити сторінку контентом — додаємо <Frame>
, у який вставимо наші IT_KPI.xaml та MS_KPI.xaml Також задаємо ім’я.
<Frame>
відображає екземпляри сторінок, підтримує навігацію на нові сторінки і містить навігаційну історію щоб надати можливість переміщатись туди-сюди по сторінкам. По суті, призначення цього елементу таке ж, як і в HTML: відображати всередині себе шматок іншої сторінки.
Код:
<SplitView Grid.Row="1">
<SplitView.Pane>
</SplitView.Pane>
<SplitView.Content>
<Frame Name="MyFrame">
</Frame>
</SplitView.Content>
</SplitView>
Для пунктів меню скористаємось елементом керування
<ListBox>
зазвичай слугує для відображення списків. Елемент являє собою блок, всередині якого розміщуються стрічки з пунктами, з-поміж яких користувач може обирати один або декілька.
Елементи <ListBox>
задаються тегом <ListBoxItem>
, які будуть слугувати пунктами меню.
В кожному пункті нам потрібно два елементи: іконка (зліва) та назва пункту (справа). Для того, щоб помістити послідовно два елементи скористаємось елементом <StackPanel>
і вкажемо її орієнтацію як горизонтальну.
<StackPanel>
багато в чому схожа на<ListBox>
, але має більше властивостей і ширше застосування. Призначена для того, щоб розташовувати різні елементи один над іншим, а не лише стрічки. Орієнтацію можна змінити на горизонтальну.
<SplitView Grid.Row="1">
<SplitView.Pane>
<ListBox> <!-- Меню -->
<ListBoxItem> <!-- Пункт меню -->
<StackPanel Orientation="Horizontal">
</StackPanel>
</ListBoxItem>
<ListBoxItem>
<StackPanel Orientation="Horizontal">
</StackPanel>
</ListBoxItem>
</ListBox>
</SplitView.Pane>
<SplitView.Content>
<Frame Name="MyFrame">
</Frame>
</SplitView.Content>
</SplitView>
В кожен тег <StackPanel>
вставляємо два текстові блоки і вписуємо в них іконки. Також дамо назви кожному <ListBoxItem>
, щоб можна було достукатись до них з обробника подій. Задамо два атрибути для <ListBox>
:
SelectionMode="Single" SelectionChanged="ListBox_SelectionChanged"
SelectionMode="Single"
говорить про те, що в кожен момент часу лише один елемент меню може бути обраний.
SelectionChanged="ListBox_SelectionChanged"
– це обробник події, що реагує на переключання пункту меню
Не забудемо про <SplitView>
і додамо йому кілька атрибутів. Ім’я, режим відображення та розміри панелі у відкритому і закритому станах.
DisplayMode="CompactOverlay" CompactPaneLength="56"
OpenPaneLength="200"
Зараз код виглядає так:
<SplitView Grid.Row="1"
Name="MySplitView"
DisplayMode="CompactOverlay"
CompactPaneLength="56"
OpenPaneLength="200">
<SplitView.Pane>
<ListBox SelectionMode="Single"
SelectionChanged="ListBox_SelectionChanged">
<ListBoxItem Name="IT_KPI">
<StackPanel Orientation="Horizontal">
<TextBlock FontFamily="Segoe MDL2 Assets"
FontSize="36"
Text=""/>
<TextBlock FontSize="24">IT KPI</TextBlock>
</StackPanel>
</ListBoxItem>
<ListBoxItem Name="MS_KPI">
<StackPanel Orientation="Horizontal">
<TextBlock FontFamily="Segoe MDL2 Assets"
FontSize="36"
Text=""/>
<TextBlock FontSize="24">MS KPI</TextBlock>
</StackPanel>
</ListBoxItem>
</ListBox>
</SplitView.Pane>
<SplitView.Content>
<Frame Name="MyFrame">
</Frame>
</SplitView.Content>
</SplitView>
Перш ніж запустити проект – мусимо додати останній штрих. Гортаємо код вгору до нашої кнопки «Гамбургер», ставимо курсор на назву обробника події у властивості Click і тиснемо F12.
Відкриється файл MainPage.xaml.cs, який містить обробники подій з нашої головної XAML-сторінки. В методі HamburgerButton_Click прописуємо одну єдину стрічку, що інвертує стан панелі <SplitView.Pane>
.
MySplitView.IsPaneOpen = !MySplitView.IsPaneOpen;
Тепер можна запускати проект і дивитись, що вийшло.
Текст трохи виглядає з меню. На щастя, це легко пофіксити, вказавши атрибут Margin="20,0,0,0"
для другого <TextBlock>
. Це змусить його посунутись на 20 пікселів праворуч.
<TextBlock FontSize="24" Margin="20,0,0,0">IT KPI</TextBlock>
…
<TextBlock FontSize="24" Margin="20,0,0,0">MS KPI</TextBlock>
Тепер маємо робочий приклад меню, який реагує на натискання кнопки «Hamburger». Час йти далі і написати трохи логіки.
Коли додаток стартує ми хочемо, щоб завантажувалась одна з XAML-сторінок і назва сторінки вгорі змінювалась. Для цього в конструкторі MainPage() прописуємо наступне:
MyFrame.Navigate(typeof(НАЗВА_СТОРІНКИ));
TitleTextBlock.Text = "НАЗВА_СТОРІНКИ";
При першому запуску з’являється головна сторінка, тому не треба, щоб кнопка «Назад» відображалась.
Приховуємо її стрічкою:
BackButton.Visibility = Visibility.Collapsed;
Оголошуємо про те, що сторінка IT_KPI.xaml тепер активна
IT_KPI.IsSelected = true;
В мене конструктор виглядає так:
public MainPage()
{
this.InitializeComponent();
MyFrame.Navigate(typeof(IT_KPI));
TitleTextBlock.Text = "IT KPI";
BackButton.Visibility = Visibility.Collapsed;
IT_KPI.IsSelected = true;
}
Змінимо вміст ListBox_SelectionChanged так, щоб він реагував на переключення пунктів меню і показував бажану сторінку.
private void ListBox_SelectionChanged
(object sender, SelectionChangedEventArgs e)
{
if (IT_KPI.IsSelected)
{
MyFrame.Navigate(typeof(IT_KPI));
TitleTextBlock.Text = "IT KPI";
}
else if (MS_KPI.IsSelected)
{
MyFrame.Navigate(typeof(MS_KPI));
TitleTextBlock.Text = "Microsoft KPI Group";
}
}
БДЩ, тепер наш додаток реагує на перемикання пунктів меню!
Задамо невеликий відступ між кнопкою «Назад» і назвою сторінки. Йдемо в MainPage.xaml, знаходимо <TextBlock>
на ім’я TitleTextBlock і дописуємо йому Margin="20,5,0,0"
. Ще не зайвим буде додати відступ у 10 пікселів для <Frame>
у самому низу:
<Frame Name="MyFrame" Margin="10">
</Frame>
Виглядає явно красивіше.
Кнопка «Назад» повинна вести на головну сторінку і зникати на ній. Натомість мусить відображатись на всіх інших сторінках. Це робиться відносно просто.
Повертаємось до нашого методу ListBox_SelectionChanged і додаємо дві стрічки, що приховують і відображають кнопку в залежності від того, на якій сторінці зараз користувач.
private void ListBox_SelectionChanged
(object sender, SelectionChangedEventArgs e)
{
if (IT_KPI.IsSelected)
{
MyFrame.Navigate(typeof(IT_KPI));
TitleTextBlock.Text = "IT KPI";
BackButton.Visibility = Visibility.Collapsed;
}
else if (MS_KPI.IsSelected)
{
BackButton.Visibility = Visibility.Visible;
MyFrame.Navigate(typeof(MS_KPI));
TitleTextBlock.Text = "Microsoft KPI Group";
}
}
Єдине, що лишилось – вдихнути трохи життя в кнопку «Назад». Прямуємо до методу BackButton_Click і наповнюємо його:
private void BackButton_Click
(object sender, RoutedEventArgs e)
{
if (MyFrame.CanGoBack)
{
MyFrame.GoBack();
IT_KPI.IsSelected = true;
}
}
Код всіх трьох методів разом з конструктором:
public MainPage()
{
this.InitializeComponent();
MyFrame.Navigate(typeof(IT_KPI));
TitleTextBlock.Text = "IT KPI";
BackButton.Visibility = Visibility.Collapsed;
IT_KPI.IsSelected = true;
}
private void HamburgerButton_Click
(object sender, RoutedEventArgs e)
{
MySplitView.IsPaneOpen = !MySplitView.IsPaneOpen;
}
private void BackButton_Click
(object sender, RoutedEventArgs e)
{
if (MyFrame.CanGoBack)
{
MyFrame.GoBack();
IT_KPI.IsSelected = true;
}
}
private void ListBox_SelectionChanged
(object sender, SelectionChangedEventArgs e)
{
if (IT_KPI.IsSelected)
{
MyFrame.Navigate(typeof(IT_KPI));
TitleTextBlock.Text = "IT KPI";
BackButton.Visibility = Visibility.Collapsed;
}
else if (MS_KPI.IsSelected)
{
BackButton.Visibility = Visibility.Visible;
MyFrame.Navigate(typeof(MS_KPI));
TitleTextBlock.Text = "Microsoft KPI Group";
}
}
Тепер можна запустити додаток і оцінити, що у нас вийшло. На цьому все, дякую за увагу! Сподіваюсь, було корисно.
Tags: dotNet, csharp