Элементы управления ToolBarTray и StatusBar

36

ToolBarTray

Хотя допускается добавлять в окно множество элементов управления Toolbar и управлять ими с помощью контейнера компоновки, в WPF есть класс, предназначенный специально для этой цели, который называется ToolBarTray. По сути, ToolBarTray хранит коллекцию объектов ToolBar (которые предоставляются через свойство ToolBars).

Класс ToolBarTray упрощает размещение панелей инструментов на одной строке, также называемой полосой (band). Его можно сконфигурировать так, чтобы одни панели инструментов размещались в одной и той же полосе, а другие — в отдельных полосах.

ToolBarTray отображает по всей площади ToolBar затененный фон. Но самым важным является то, что ToolBarTray дополнительно предоставляет поддержку для функции перетаскивания панелей инструментов. Если только свойство ToolBarTray.IsLocked не установлено в true, пользователь может переупорядочивать находящиеся в ToolBarTray панели инструментов, щелкая на специальном значке захвата с левой стороны.

Панели инструментов можно передвигать как в пределах одной и той же полосы, так и перемещать в другие полосы. Однако перетаскивать панель инструментов из одного элемента управления ToolBarTray в другой нельзя. Чтобы заблокировать возможность перемещения панелей инструментов, необходимо установить в true присоединенное свойство ToolBarTray.IsLocked для соответствующих объектов ToolBar.

При перемещении панелей инструментов некоторая часть их содержимого может стать трудной для восприятия. Например, пользователь может переместить панель инструментов в позицию, практически не оставляющую места для соседней панели инструментов. В такой ситуации все загораживаемые элементы управления перемещаются в дополнительное меню.

В ToolBarTray разрешено размещать столько объектов ToolBar, сколько нужно. По умолчанию все добавленные панели инструментов располагаются в самой верхней полосе в порядке слева направо. Первоначально каждая панель инструментов занимает всю необходимую ей ширину. (Если следующая панель инструментов не умещается, некоторые или все ее кнопки переносятся в дополнительное меню.) Для достижения большего контроля можно указать, какую именно полосу должна занимать данная панель инструментов, указав в свойстве Band числовой индекс (где 0 соответствует самой верхней полосе). Допускается также явно задать нужную позицию расположения внутри полосы с помощью свойства BandIndex. В случае установки BandIndex в 0 панель инструментов размещается в начале полосы.

Ниже приведен пример кода разметки, который создает в ToolBarTray несколько панелей инструментов. Результат можно видеть на рисунке:

<ToolBarTray>
                    <ToolBar>
                        <Button>
                            <Image Source="open-sign.png" MaxHeight="32"></Image>
                        </Button>
                        <Separator></Separator>
                        <Button>New</Button>
                        <Button>Open</Button>
                        <Button>Close</Button>
                        <Separator></Separator>
                        <CheckBox FontWeight="Bold">Bold</CheckBox>
                        <CheckBox FontStyle="Italic">Italic</CheckBox>
                        <CheckBox>
                            <TextBlock TextDecorations="Underline">Underline</TextBlock>
                        </CheckBox>
                        <Separator></Separator>
                        <ComboBox SelectedIndex="1">
                            <ComboBoxItem>50%</ComboBoxItem>
                            <ComboBoxItem>100%</ComboBoxItem>
                            <ComboBoxItem>150%</ComboBoxItem>
                        </ComboBox>
                    </ToolBar>
                    <ToolBar>
                        <Button>A</Button>
                        <Button>B</Button>
                        <Button>C</Button>
                    </ToolBar>
                    <ToolBar Band="1">
                        <Button>Red</Button>
                        <Button>Green</Button>
                        <Button>Yellow</Button>
                        <Button>White</Button>
                    </ToolBar>
     </ToolBarTray>
Группирование элементов в ToolBarTray

StatusBar

По сравнению с ToolBar, класс StatusBar является куда менее изощренным. Подобно ToolBar он удерживает любое содержимое (упаковывая его неявным образом в объекты StatusBarItem) и переопределяет используемые по умолчанию стили некоторых элементов для обеспечения более подходящей визуализации. Однако поддержки для перегруппирования элементов за счет перетаскивания и создания дополнительного меню элемент управления StatusBar не включает. В основном его применяют для отображения текста и графических индикаторов (изредка — панели хода выполнения).

Элемент управления StatusBar не очень подходит, когда требуется использовать один из элементов, унаследованных от ButtonBase, или элемент ComboBox. Он не переопределяет стилей ни одного из этих элементов управления, из-за чего они выглядят в строке состояния так, будто бы находятся не на своем месте. При необходимости создать строку состояния, включающую именно такие элементы управления, лучше рассмотреть вариант стыковки к нижней части окна обычного элемента управления ToolBar.

Возможно, именно из-за этой общей нехватки функциональности StatusBar и находится в пространстве имен System.Windows.Controls.Primitives, а не в более универсальном пространстве имен System.Windows.Controls, где определен элемент управления ToolBar.

Тем, кто решит использовать строку состояния, стоит знать о следующем. Обычно элемент управления StatusBar компонует свои дочерние элементы слева направо с помощью объекта StackPanel с горизонтальной ориентацией. Однако в приложениях элементы строки состояния довольно часто имеют пропорциональные размеры или прикреплены к правой стороне строки состояния. Реализовать такой дизайн можно за счет указания того, что в строке состояния должна использоваться другая панель, с помощью свойства ItemsPanelTemplate.

Один из способов получить пропорциональные или правильно выровненные элементы — применить в качестве контейнера компоновки элемент управления Grid. Единственной сложностью является то, что для установки свойства GridColumn подходящим образом дочерний элемент нужно обязательно упаковать в объект StatusBarItem. Ниже приведен пример, в котором один элемент TextBlock размещается в левой части StatusBar, а другой — в правой:

<Grid>
                <Grid.RowDefinitions>
                    <RowDefinition></RowDefinition>
                    <RowDefinition Height="auto"></RowDefinition>
                </Grid.RowDefinitions>
                <StatusBar Grid.Row="1">
                    <StatusBar.ItemsPanel>
                        <ItemsPanelTemplate>
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="*"></ColumnDefinition>
                                    <ColumnDefinition Width="auto"></ColumnDefinition>
                                </Grid.ColumnDefinitions>
                            </Grid>
                        </ItemsPanelTemplate>
                    </StatusBar.ItemsPanel>
                    <TextBlock>Текст слева</TextBlock>
                    <StatusBarItem Grid.Column="1">
                        <TextBlock>Текст справа</TextBlock>
                    </StatusBarItem>
                </StatusBar>
            </Grid>

Здесь становится очевидным одно из главных преимуществ WPF другие элементы управления могут извлекать пользу из базовой модели компоновки без необходимости ее воссоздания. В состав Windows Forms тоже входило несколько элементов управления, способных упаковывать нечто вроде пропорциональных элементов, в числе которых StatusBar и DataGridView. Несмотря на концептуальный сценарий, эти элементы управления были вынуждения включать собственную модель компоновки и добавлять собственные, касающиеся компоновки свойства для управления дочерними элементами. В WPF такого нет: здесь каждый элемент управления, который наследуется от ItemsControl, может использовать любую панель для организации своих дочерних элементов.

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