Статьи

Подумайте дважды, прежде чем помещать другую сетку в окно WPF

Прежде чем я продолжу эту дискуссию, я должен сказать, что я ничего не имею против гридов или любых контейнерных элементов управления, которые можно использовать в приложении WPF. Я говорю о возможном неправильном использовании сетки, вызванной устаревшими привычками, а также о хорошем решении для реализации той же функциональности.

Итак, вот план — я работаю над приложением, которое имеет несколько отдельных зон. Существует боковая панель, пользовательская строка состояния и зона, предназначенная для пользовательской панели инструментов. Общий макет для этого будет выглядеть так:

Итак, какова первая идея, которая приходит на ум, когда вам нужно реализовать это? Если бы вы работали с приложением WinForms, вы, вероятно, добавили бы в форму несколько элементов управления Panel и правильно закрепили их. Некоторые разработчики, которые переходят с Windows Forms на WPF, часто пытаются сделать то же самое в приложении WPF.

Чего они не знают (пока), так это того, что такой подход обычно неверен. Не то чтобы это имело ужасные последствия, но оно обеспечит использование некоторых дополнительных элементов управления, которых можно было бы избежать.

Так что же с добавлением еще нескольких сеток в окно? Прежде всего, если я захочу воссоздать структуру пользовательского интерфейса, как показано на рисунке выше, у меня должно быть как минимум три сетки (выделено — вы можете рассмотреть любой контейнерный элемент управления там). И вы могли бы на самом деле рассмотреть добавление четвертого контейнера для основного контента. Четыре дополнительных элемента управления, которые должны быть правильно закреплены и закреплены внутри формы — не самый лучший вариант, когда вы планируете работать над большим количеством изменений пользовательского интерфейса, поскольку это может создать беспорядок — когда вы будете неправильно привязывать что-либо, это может в конечном итоге вызывают совпадения и смещения.

Альтернативным сценарием для этого было бы использование одной сетки и разделение ее на несколько строк и столбцов (хотя я пока не вижу массового принятия этого метода для использования элемента управления Grid ). Для показанного интерфейса я создал образец окна:

<Window x:Class="WPF_SB.MainWindow"        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"        Title="MainWindow" Height="350" Width="525">    <Grid>    </Grid></Window>

Теперь внутри элемента разметки Grid я могу определить конкретные строки, которые будут присутствовать внутри основной сетки. Это делается через Grid.RowDefinitions :

<Grid.RowDefinitions>    <RowDefinition Height="70"></RowDefinition>    <RowDefinition Height="*"></RowDefinition>    <RowDefinition Height="20"></RowDefinition></Grid.RowDefinitions>

Теперь у меня есть три отдельных строки, которые делают сетку похожей на это:

Для первой и последней строки я явно определяю высоту, а для средней я просто указываю, что она займет оставшееся пространство.

Мне также нужен столбец для боковой панели, поэтому все, что мне нужно сделать, это установить Grid.ColumnDefinitions :

<Grid.ColumnDefinitions>    <ColumnDefinition Width="150"></ColumnDefinition>    <ColumnDefinition Width="*"></ColumnDefinition></Grid.ColumnDefinitions>

Это оно! У вас есть базовая структура для настройки пользовательского интерфейса. Теперь вы можете ссылаться на элементы управления на их собственную ячейку, используя свойства Grid.Row и Grid.Column . Например, если я хочу разместить элемент управления TextBox внутри основной (самой большой) ячейки, я могу сделать это следующим образом (учитывая, что элемент управления находится внутри определенной сетки):

<TextBox Grid.Row="1" Grid.Column="1"></TextBox>

Но как насчет заполнителя панели инструментов ленты? Очевидно, в верхней строке есть две ячейки, и нет возможности установить свойство Grid.Column дважды, но я бы хотел, чтобы оно охватывало обе ячейки. В этом случае Grid.ColumnSpan позволяет сохранить день и дает возможность распределить элемент управления по нескольким столбцам.

Вот пример, где я размещаю кнопку над двумя верхними столбцами:

<Button Grid.ColumnSpan="2" Content="Test"></Button>

Поскольку начальная точка — самый верхний левый угол, мне не нужно указывать столбец и строку контейнера. Свойство ColumnSpan определяет количество столбцов, на которые будет распространяться элемент управления.

То же самое можно сделать со строками, и одну и ту же кнопку можно растянуть по всей боковой панели — все три строки с помощью RowSpan :

<Button Grid.RowSpan="3" Content="Test"></Button>

Что мне действительно нравится в этом методе, так это то, что в конце концов мне не нужно самостоятельно обрабатывать стыковку и привязку (при необходимости) для базовой компоновки. Таким образом, я могу легко изменить пользовательский интерфейс, не беспокоясь о возможных совпадениях или смещениях, поскольку все предназначено для определенного столбца и / или строки.