Группы с общими размерами

48

Grid содержит коллекцию строк и колонок, размер которых устанавливается явно, пропорционально или на основе размеров их дочерних элементов. Существует только один способ изменить размер строки или колонки — приравнять его к размеру другой строки или колонки. Это выполняется с помощью средства, которое называется группы с общими размерами (shared size groups).

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

Чтобы понять, как это работает, рассмотрим пример, в котором окно оснащено двумя объектами Grid — один в верхней части окна (с тремя колонками) и один в его нижней части (с двумя колонками). Размер левой крайней колонки первого Grid устанавливается пропорционально ее содержимому (длинной текстовой строке). Левая крайняя колонка второго Grid имеет в точности ту же ширину, хотя имеет меньшее содержимое. Дело в том, что они входят в одну размерную группу. Независимо от того, какое содержимое вы поместите в первую колонку первого Grid, первая колонка второго Grid останется синхронизированной.

<Grid Grid.IsSharedSizeScope="True">
        <Grid.RowDefinitions>
            <RowDefinition></RowDefinition>
            <RowDefinition Height="auto"></RowDefinition>
            <RowDefinition></RowDefinition>
        </Grid.RowDefinitions>
        <Grid Grid.Row="0" ShowGridLines="True">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="auto" SharedSizeGroup="SomeText"></ColumnDefinition>
                <ColumnDefinition Width="auto"></ColumnDefinition>
                <ColumnDefinition></ColumnDefinition>
            </Grid.ColumnDefinitions>
            <Label>Длинный текст</Label>
            <Label Grid.Column="1">Другой текст</Label>
            <TextBlock Grid.Column="2" Padding="5">Элемент TextBlock</TextBlock>
        </Grid>
        <Label Grid.Row="1">Текст между двумя элементами Grid</Label>
        <Grid Grid.Row="2" ShowGridLines="True">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="auto" SharedSizeGroup="SomeText"></ColumnDefinition>
                <ColumnDefinition></ColumnDefinition>
            </Grid.ColumnDefinitions>
            <Label>Текст</Label>
            <TextBlock Grid.Column="1" Padding="5">TextBlock in Grid2</TextBlock>
        </Grid>
</Grid>
Два элемента Grid разделяющие одно окно

Как демонстрирует этот пример, колонки с общими размерами могут принадлежать к разным элементам Grid. В этом примере верхний Grid имеет на одну колонку больше и потому оставшееся пространство в нем распределяется иначе. Аналогично колонки с общими размерами могут занимать разные позиции, так что можно создать отношение между первой колонкой одного Grid и второй колонкой другого. И очевидно, что колонки при этом могут иметь совершенно разное содержимое.

Когда применяется группа с общими размерами, это все равно, как если бы создавалось одно определение колонки (или строки), используемое в более чем одном месте. Это не просто однонаправленная копия одной колонки в другую. В этом можно убедиться, изменив в предыдущем примере содержимое разделенной колонки второго Grid. Теперь колонка в первом Grid будет удлинена для сохранения соответствия:

Форматирующие колонки

Можно даже добавить GridSplitter к одному из объектов Grid. Когда пользователь будет изменять размер колонки в одном Grid, то соответствующая разделенная колонка из второго Grid также будет синхронно менять свой размер.

Создать группы с общими размерами просто. Понадобится лишь установить свойство SharedSizeGroup в обеих колонках, используя строку соответствия. В текущем примере обе колонки используют группу по имени SomeText.

Осталось упомянуть еще одну деталь. Группы с общими размерами не являются глобальными для всего приложения, потому что более одного окна могут непреднамеренно использовать одно и то же имя. Можно предположить, что группы с общими размерами ограничены текущим окном, но на самом деле платформа WPF еще более строга в этом отношении. Чтобы разделить группу, необходимо явно установить присоединенное свойство Grid.IsSharedSizeScope в true в контейнере высшего уровня, содержащем объекты Grid, который имеет колонки с общими размерами. В текущем примере верхний и нижний Grid входят в другой Grid, предназначенный для этой цели, хотя столь же просто можно применить другой контейнер, такой как DockPanel или StackPanel.

Для синхронизации отдельных Grid с заголовками колонок можно было бы использовать группу с общими размерами. Ширина каждой колонки может быть затем определена ее содержимым, которое разделит заголовок. Допускается даже поместить GridSplitter в заголовок, и тогда пользователь сможет перетаскивать его для изменения размера заголовка и всей лежащей ниже колонки.

Пройди тесты
Лучший чат для C# программистов