C# + XAML = Hamburger Menu. Part 1

Іконка гамбургера — це класика. Навіть якщо ви не знаєте її під цим ім’ям, то три чорні смуги настільки ж знайомі, як курсор миші — постійний супутник нашого інтернет-серфінгу з того дня, як ви отримали комп’ютер.

Gizmodo

Кнопка “Hamburger” зустрічається майже усюди. Від Android-додатків до мобільних версій знаменитих сайтів. Хтось зве її антипатерном UI, хтось боготворить за зручність і зрозумілість.

Так чи інакше, кнопка з трьома горизонтальними рисками у нашому житті надовго. І сьогодні ми навчимось готувати гамбургер самостійно.

Ключові інгредієнти страви:

Дві ремарки перед тим, як почнемо:

  • в деяких місцях форматування коду поїхало, бо не влізає по ширині. При копіюванні у Visual Studio все красиво, тому feel free to use Ctrl+C and Ctrl+V
  • текст, що виділений як цитата, надає додаткову інформацію. Його можна не читати.

Отже, поїхали.

Велика подорож починається з першого кроку, а написання крутого додатку — зі створення проекту. Обираємо Blank App і тиснемо «Ok».

Оберіть дві картинки на свій смак і перетягніть їх в папку Assets. Згодом ми будемо міняти їх місцями, перемикаючи пункти нашого «Hamburger» меню.

Картинки помістимо на окремі XAML-сторінки і будемо переключати їх всередині фрейму. Про це в деталях трохи згодом, зараз просто додаємо дві порожні сторінки в проект. Натискаємо правою кнопкою миші на назві проекту, Add => New Item. Обираємо Blank Page, задаємо ім’я і клацаємо «Ок»

В HTML сторінка складається з двох частин. Тег містить атрибути, які допомагають браузеру коректно відображати вміст. В той же час зберігає сам контент, який необхідно показати.

Якщо провести аналогію, то XAML-сторінку можна умовно розбити на частину з оголошенням просторів імен і, власне, контентом. Вгорі сторінки міститься стовпець xmlns–тегів, що вказують на різні схеми. Якщо спростит — в цих схемах міститься інформація про елементи керування (controls), їх властивості, правила створення об’єктів з XAML-коду і все-все-все. Ці штуки краще не займати, а якщо дуже хочеться хоч трохи зрозуміти їх призначення — можна почитати тут або в книзі Маргарити Остапчук і Сергія Байдачного про розробку під Windows 10 тут (сторінка 27).

Нижче під просторами імен побачите елемент керування <Grid>. Він розбиває видимий простір на сітку з рядків і стовпців. Додаємо зображення до <Grid> на сторінках IT_KPI.xaml та MS_KPI.xaml.

Для цього використовується тег <Image>. Атрибут Source вказує шлях до картинки, а VerticalAlignment прив’язує зображення до верху сторінки.

Додаємо наступний код всередину тега <Grid>:

<Image Source="Assets/НАЗВА_ЗОБРАЖЕННЯ.jpg" VerticalAlignment="Top" />

В результаті маємо:

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
  <Image Source="Assets/1.jpg" VerticalAlignment="Top" />
</Grid>

Ще один важливий момент: за замовчуванням у нашому додатку буде висвічуватись лічильник FPS.

Часто дуже корисна штука, але не вписується в наш космічний дизайн. Щоб позбутись від нього мусимо перейти в App.xaml.cs і видалити наступний шматок коду.

Підготовчий етап завершено, приступаємо до найцікавішого. Йдемо в MainPage.xaml і розбиваємо сторінку на дві стрічки. Як вже згадували, для цього служить <Grid>. Кількість рядків і стовпців задається властивостями (property) під назвою <Grid.RowDefinitions> та <Grid.ColumnDefinitions>. Ми хочемо розбити сторінку на два горизонтальні рядки, тому додаємо відповідні теги.

Маємо наступний код:

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
</Grid>

Height="Auto" говорить про те, що висота елементу буде визначатись висотою його вмісту. Якщо всередину першого рядка помістити кнопку з властивістю Height="50", то висота рядка також буде 50 пікселів.

Height="*" говорить рядку: «Займи весь вільний простір, який знайдеш». Певно, схожа команда є всередині браузера Google Chrome і стосується оперативної пам’яті.

Нижче додамо <RelativePanel>, яка зберігатиме кнопку гамбургера, кнопку «Назад» і панель пошуку.

<RelativePanel> — це контейнер для взаємного позиціонування елементів керування один відносно одного. Застосовуючи прикріплені властивості (attached properties) можна розташувати один елемент відносно іншого, або приліпити елемент до самої панелі. Детальніше тут.

Ще нижче додамо <SplitView>, в якому буде знаходитись саме тіло меню. Нащо він треба і як працює буде описано, коли до нього дійде черга. Зараз просто допишемо його під <RelativePanel> і заб’ємо.

На даному етапі код виглядає так:

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>

    <RelativePanel>
    </RelativePanel>

    <SplitView>
    </SplitView>
</Grid>

Всередину <RelativePanel> додаємо головну кнопку з трьома горизонтальними рисками, на честь якої і назвали дизайн меню. Також покладемо туди кнопку «Назад», текстовий блок з назвою сторінки і панель пошуку, роль якої буде виконувати поле та кнопка.

Код <RelativePanel>. Також необхідно дати імена усім нашим елементам.

<RelativePanel>
   <Button Name="HamburgerButton" />     
   <Button Name="BackButton"/>          
   <TextBlock Name="TitleTextBlock"/>    
   <TextBox Name="SearchTextBox"/>       
   <Button Name="SearchButton" />             
</RelativePanel>

Як було сказано, <RelativePanel> служить для відносного позиціонування своїх дочірніх елементів. «Гамбургер» знаходиться зліва. Кнопка «Назад» буде знаходитись праворуч від «Гамбургера». Назва сторінки — праворуч від «Назад», меню пошуку потрібно розмістити справа відносно панелі. Для цього задаємо відповідні властивості.

Тепер код має наступний вигляд:

<RelativePanel>
        <Button Name="HamburgerButton" 
                RelativePanel.AlignLeftWithPanel="True"/>    
     
        <Button Name="BackButton"
                RelativePanel.RightOf="HamburgerButton"/>  
      
        <TextBlock Name="TitleTextBlock"
                   RelativePanel.RightOf="BackButton"/>      

        <TextBox Name="SearchTextBox" 
                 RelativePanel.LeftOf="SearchButton"/>

        <Button Name="SearchButton" 
                RelativePanel.AlignRightWithPanel="True"/>
</RelativePanel>

Властивості можна переміщати на наступну стрічку для покращення читабельності. Синтаксис це дозволяє.

Тепер головне — призначаємо знамениту іконку «Hamburger». Для відображення трьох горизонтальних рисок на кнопці використовується спеціальний шрифт, що зветься «Segoe MDL2 Assets». Символи цього шрифту можна знайти у всіх сучасних програмах Microsoft і не тільки.

Щоб глянути всі доступні символи та їх коди достатньо запустити програму «Таблиця символів» (Character map). Вона стандартна, застосуйте пошук по комп’ютеру.

Нас же цікавить код кнопки «Меню», «Назад» та «Пошук»

Для присвоєння символу кнопці пишемо наступні властивості:

FontFamily="Segoe MDL2 Assets"
Content="&#xCODE;"

Де CODE – код кнопки. Для менюхи, «назад» і «пошук» коди E700, E0C4 та E1A3 відповідно.

Розмір шрифту задається властивістю FontSize. Ставимо його рівним 36.

FontSize="36"

Також для кожної кнопки додаємо обробник події, що реагує на натискання. Коли користувач тикне на кнопку ми хочемо, щоб відбувались певні дії. Ці дії і будуть визначатись обробником Click.

Вставляємо в кнопки «Меню» і «Назад» властивість

Click="НАЗВА_КНОПКИ_Click"

Для кнопки пошуку обробник не потрібен, в нас же нічого шукати.

Вміст <RelavivePanel> виглядає так:

 <RelativePanel>
        <Button Name="HamburgerButton" 
                RelativePanel.AlignLeftWithPanel="True"
                FontFamily="Segoe MDL2 Assets"
                FontSize="36"
                Content="&#xE700;"
                Click="HamburgerButton_Click"/> 
        
        <Button Name="BackButton"
                RelativePanel.RightOf="HamburgerButton"
                FontFamily="Segoe MDL2 Assets"
                FontSize="36"
                Content="&#xE0C4;"
                Click="BackButton_Click"/>
        
        <TextBlock Name="TitleTextBlock"
                   RelativePanel.RightOf="BackButton"
                   FontSize="28"/>``            
             
        <TextBox Name="SearchTextBox" 
                 RelativePanel.LeftOf="SearchButton"
                 Height="48" 
                 Width="200"
                 FontSize="24"
                 PlaceholderText="Search"/>

        <Button Name="SearchButton" 
                RelativePanel.AlignRightWithPanel="True"
                FontFamily="Segoe MDL2 Assets"
                FontSize="36"
                Content="&#xE1A3;"/>
 </RelativePanel>

Настав час підпалити проект. Тикаємо F5 і маємо наступний результат:

Продовження епопеї читайте тут

Tags: dotNet, csharp