Table of Contents

Начало работы с панелями инструментов

В этом руководстве показано, как использовать библиотеку панелей инструментов Eremex для создания пользовательского интерфейса панели инструментов с нуля. В нем представлены контролы для реализации пользовательского интерфейса панели инструментов и демонстрируются свойства основных панелей инструментов.

toolbar-ui-tutorial

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

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

В руководстве также показано, как привязать текстовый редактор к контекстному меню из Библиотеки Панелей Инструментов и Меню.

1. Создание компонента ToolbarManager

Начните с определения компонента ToolbarManager в XAML.

xmlns:mxb="clr-namespace:Eremex.AvaloniaUI.Controls.Bars;assembly=Eremex.Avalonia.Controls"

<Window.DataContext>
    <local:MainViewModel/>
</Window.DataContext>

<mxb:ToolbarManager IsWindowManager="True">
    <Grid RowDefinitions="Auto, *, Auto, *, Auto" ColumnDefinitions="Auto, *, Auto">
        <TextBox Grid.Row="1" Grid.Column="1" x:Name="textBox1"  Text="Text Editor" AcceptsReturn="True"/>
        <TextBox x:Name="textBox2"  Grid.Row="3" Grid.Column="1" Text="Text Editor #2" AcceptsReturn="True"/>
    </Grid>
</mxb:ToolbarManager>            

ToolbarManager - это основной компонент, который управляет панелями инструментов, контекстными меню и элементами меню. Компонент обрабатывает горячие клавиши, вызывает команды, связанные с соответствующими элементами, поддерживает настройку среды выполнения панели инструментов и выполняет сериализацию и десериализацию пользовательского интерфейса панели.

Компонент ToolbarManager должен обернуть клиентский контрол (контролы), для которого создан пользовательский интерфейс панели инструментов.

2. Создание контейнеров панелей инструментов

Чтобы разрешить пристыковывать панель инструментов к определенной позиции в окне/UserControl, сначала создайте контейнер панели инструментов (ToolbarContainerControl). Контейнер панели инструментов - это контрол, который отображает панели инструментов в пристыкованном состоянии и поддерживает операции перетаскивания панели инструментов.

В XAML создайте четыре контейнера панели инструментов (объекты ToolbarContainerControl) вдоль верхнего, нижнего, левого и правого краев окна. После этого вы сможете, чтобы пристыковать панели инструментов в этих позициях.

toolbars-get-started-empty=toolbarcontainers

xmlns:mxb="clr-namespace:Eremex.AvaloniaUI.Controls.Bars;assembly=Eremex.Avalonia.Controls"

<mxb:ToolbarManager IsWindowManager="True">
    <Grid RowDefinitions="Auto, *, Auto, *, Auto" ColumnDefinitions="Auto, *, Auto">
        <mxb:ToolbarContainerControl DockType="Top" Grid.ColumnSpan="3"/>

        <mxb:ToolbarContainerControl DockType="Left" Grid.Row="1" Grid.Column="0" Grid.RowSpan="3" />

        <TextBox Grid.Row="1" Grid.Column="1" x:Name="textBox1"  Text="Text Editor" AcceptsReturn="True"/>
        <TextBox x:Name="textBox2"  Grid.Row="3" Grid.Column="1" Text="Text Editor #2" AcceptsReturn="True"/>

        <mxb:ToolbarContainerControl DockType="Right" Grid.Row="1" Grid.Column="2" Grid.RowSpan="3"/>

        <mxb:ToolbarContainerControl DockType="Bottom" Grid.Row="4" Grid.ColumnSpan="3"/>
    </Grid>
</mxb:ToolbarManager>

Опции контейнера панелей инструментов

Основным свойством ToolbarContainerControl является ToolbarContainerControl.DockType, которое определяет, как контейнер пристыкован к своему родительскому элементу. Вы можете установить свойство DockType равным Left, Right, Top, Bottom и Standalone.

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

toolbars-get-started-toolbarcontainer-docktype-left

3. Создание панелей инструментов

Добавьте панели инструментов (объекты Toolbar) в необходимые контейнеры панелей инструментов.

toolbars-get-started-empty-toolbars

xmlns:mxb="clr-namespace:Eremex.AvaloniaUI.Controls.Bars;assembly=Eremex.Avalonia.Controls"

<mxb:ToolbarManager IsWindowManager="True">
    <Grid RowDefinitions="Auto, *, Auto, *, Auto" ColumnDefinitions="Auto, *, Auto">
        <mxb:ToolbarContainerControl DockType="Top" Grid.ColumnSpan="3">
            <mxb:Toolbar x:Name="MainMenu" ToolbarName="Main Menu" DisplayMode="MainMenu">
            </mxb:Toolbar>

            <mxb:Toolbar x:Name="EditToolbar" ToolbarName="Edit" ShowCustomizationButton="True">
            </mxb:Toolbar>

            <mxb:Toolbar x:Name="FontToolbar" ToolbarName="Font" ShowCustomizationButton="True">
            </mxb:Toolbar>
        </mxb:ToolbarContainerControl>

        <mxb:ToolbarContainerControl DockType="Left" Grid.Row="1" Grid.Column="0" Grid.RowSpan="3">
            <mxb:Toolbar x:Name="TextEditingToolbar" ToolbarName="Text Editing" ShowCustomizationButton="True" >
            </mxb:Toolbar>
        </mxb:ToolbarContainerControl>
                
        <TextBox Grid.Row="1" Grid.Column="1" x:Name="textBox1"  Text="Text Editor" AcceptsReturn="True" CornerRadius="0" FontFamily="Arial" FontSize="20"/>
        <TextBox x:Name="textBox2"  Grid.Row="3" Grid.Column="1" Text="Text Editor #2" AcceptsReturn="True" CornerRadius="0" FontFamily="Arial" FontSize="20"/>

        <mxb:ToolbarContainerControl DockType="Right" Grid.Row="1" Grid.Column="2" Grid.RowSpan="3"/>

        <mxb:ToolbarContainerControl DockType="Bottom" Grid.Row="4" Grid.ColumnSpan="3">
            <mxb:Toolbar DisplayMode="StatusBar" ToolbarName="Status Bar" x:Name="StatusBar">
            </mxb:Toolbar>
        </mxb:ToolbarContainerControl>
    </Grid>
</mxb:ToolbarManager>

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

Главное меню и панель состояния

Чтобы указать, что панель инструментов является главным меню или панелью состояния, установите для ее свойства Toolbar.DisplayMode значения MainMenu и StatusBar соответственно.

<mxb:Toolbar x:Name="MainMenu" ToolbarName="Main Menu" DisplayMode="MainMenu">
</mxb:Toolbar>

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

toolbars-get-started-mainmenu-statusbar

Опции панели инструментов

Объекты Toolbar предоставляют множество опций для настройки их вида, размещения и свойств поведения. Некоторые из этих опций включают:

  • ToolbarName — Отображаемое имя панели инструментов. Названия панелей инструментов отображаются в окне настройки, а также когда панель инструментов находится в плавающем состоянии.

    toolbars-get-started-toolbarname

  • ShowCustomizationButton — Определяет видимость кнопки настройки, используемой для активации режима настройки и открытия окна настройки.

    toolbars-get-started-customization-button

  • AllowDragToolbar — Определяет видимость маркера перетаскивания, который позволяет пользователям перетаскивать панель инструментов.

    toolbars-get-started-customization-drag-thumb

  • DockType — Это свойство позволяет перемещать панель инструментов в определенный контейнер панели инструментов в коде или делать панель инструментов плавающей.

  • StretchToolbar — Включает растягивание панели инструментов. В этом режиме никакая другая панель инструментов не может отображаться в той же строке.

  • WrapItems — Включает многорядное размещение панели инструментов.

4. Создание элементов панели инструментов

Следующим шагом является заполнение панелей инструментов элементами панели инструментов: обычными кнопками, кнопками-переключателями, встроенными редакторами, подменю и текстовыми элементами. Элементы панели инструментов инкапсулируются классами, производными от класса ToolbarItem, который предоставляет общие опции элемента панели инструментов.

В этом руководстве создаются следующие элементы панели инструментов:

ToolbarButtonItem

Обычная кнопка, которая запускает команду, указанную свойством Command.

toolbars-get-started-ToolbarButtonItem

<mxb:Toolbar x:Name="EditToolbar" ToolbarName="Edit" ShowCustomizationButton="True"  >
    <mxb:ToolbarButtonItem Header="Cut" Command="{Binding #textBox1.Cut}" IsEnabled="{Binding #textBox1.CanCut}" Glyph="{SvgImage 'avares://bars_sample/Images/Toolbars/EditCut.svg'}" Category="Edit"/>
    <mxb:ToolbarButtonItem Header="Copy" Command="{Binding #textBox1.Copy}" IsEnabled="{Binding #textBox1.CanCopy}" Glyph="{SvgImage 'avares://bars_sample/Images/Toolbars/EditCopy.svg'}" Category="Edit"/>
</mxb:Toolbar>

Общие опции элементов панели инструментов

Базовый класс ToolbarItem предоставляет общие опции, наследуемые всеми элементами панели инструментов. Некоторые из этих опций включают:

  • Alignment — Выравнивание элемента на панели инструментов.
  • Category — категория, к которой принадлежит элемент. Категории используются для организации элементов в логические группы в окне настройки.
  • Command — Команда, выполняемая при нажатии на кнопку.
  • CommandParameter — Командный параметр, передаваемый указанной команде.
  • DisplayMode — Определяет, отображать ли только картинку, заголовок или и то, и другое.
  • Header — Текст для отображения элемента.
  • Glyph — Картинка элемента.
  • GlyphAlignment — Выравнивание картинки относительно заголовка элемента.
  • GlyphSize — Размер отображаемой картинки.
  • ShowSeparator — Позволяет отображать разделитель перед элементом.

Присвоение всплывающего контрола/меню элементу ToolbarButtonItem

Вы можете привязать контрол/меню всплывающего окна к объекту ToolbarButtonItem. Всплывающее окно активируется щелчком по стрелке встроенного всплывающего окна или по самому элементу (смотрите опцию DropDownArrowVisibility ниже для получения дополнительной информации).

Давайте привяжем кнопку Paste (ToolbarButtonItem) к всплывающему окну меню. В меню всплывающего окна отобразятся команды Paste и Paste As.

toolbars-get-started-pastebutton-with-dropdown-menu

<mxb:ToolbarButtonItem Header="Paste" Command="{Binding #textBox1.Paste}" IsEnabled="{Binding #textBox1.CanPaste}" Glyph="{SvgImage 'avares://bars_sample/Images/Toolbars/EditPaste.svg'}" Category="Edit">
    <mxb:ToolbarButtonItem.DropDownControl>
        <mxb:PopupMenu>
            <mxb:ToolbarButtonItem Header="Paste" Command="{Binding #textBox1.Paste}" IsEnabled="{Binding #textBox1.CanPaste}" Glyph="{SvgImage 'avares://bars_sample/Images/Toolbars/EditPaste.svg'}"/>
            <mxb:ToolbarButtonItem Header="Paste As" Command="{Binding PasteAsCommand}" IsEnabled="{Binding #textBox1.CanPaste}"/>
        </mxb:PopupMenu>
    </mxb:ToolbarButtonItem.DropDownControl>
</mxb:ToolbarButtonItem>

Следующие свойства используются для указания контрола всплывающего окна и способа его отображения:

  • DropDownControl — Получает или устанавливает контрол/меню всплывающего окна, связанные с элементом. Это свойство принимает объекты PopupContainer и PopupMenu.

  • DropDownArrowVisibility — Указывает, отображает ли элемент стрелку всплывающего окна, используемую для вызова связанного контрола всплывающего окна. Поддерживаемые опции включают:

    • ShowArrow — Видна стрелка всплывающего окна. Элемент и стрелка действуют как единая кнопка. Щелчок по ним отображает связанный контрол всплывающего окна.

    • ShowSplitArrow или Default — Видна стрелка всплывающего окна. Она действует как отдельная кнопка, встроенная в элемент. Щелчок по стрелке всплывающего окна вызывает связанный с ним контрол всплывающего окна. Щелчок по элементу вызывает его команду.

    • Hide — Стрелка всплывающего окна скрыта. Щелчок по элементу вызывает контрол всплывающего окна.

ToolbarMenuItem

Кнопка, вызывающая подменю. Чтобы добавить элементы в подменю, определите их между начальным и конечным тегами <ToolbarMenuItem> в разметке XAML или добавьте их в коллекцию Items.

toolbars-get-started-ToolbarMenuItem

<mxb:Toolbar x:Name="MainMenu" ToolbarName="Main Menu" DisplayMode="MainMenu">
    <mxb:ToolbarMenuItem Header="File" Category="File">
        <mxb:ToolbarButtonItem Header="New" Glyph="{SvgImage 'avares://bars_sample/Images/Toolbars/FileNew.svg'}" Category="File" Command="{Binding NewFileCommand}"/>
        <mxb:ToolbarButtonItem Header="Open" Glyph="{SvgImage 'avares://bars_sample/Images/Toolbars/FileOpen.svg'}" Category="File" Command="{Binding OpenFileCommand}"/>
        <mxb:ToolbarButtonItem Header="Print" Glyph="{SvgImage 'avares://bars_sample/Images/Toolbars/FilePrint.svg'}" Category="File" Command="{Binding PrintCommand}" ShowSeparator="True"/>
    </mxb:ToolbarMenuItem>
</mxb:Toolbar>

Вы можете добавить в подменю все поддерживаемые типы элементов.

ToolbarCheckItem

Кнопка-переключатель, которая может находиться как в обычном, так и в нажатом состоянии.

toolbars-get-started-ToolbarCheckItem

<mxb:Toolbar x:Name="FontToolbar" ToolbarName="Font" ShowCustomizationButton="False">
    <mxb:ToolbarCheckItem Header="Bold" IsChecked="{Binding #textBox1.FontWeight, Converter={local:BoolToFontWeightConverter}, Mode=TwoWay}" Glyph="{SvgImage 'avares://bars_sample/Images/Toolbars/FontBold.svg'}" Category="Font"/>
    ...
</mxb:Toolbar>

Опции ToolbarCheckItem

  • IsChecked — Возвращает или устанавливает состояние нажатия кнопки.
  • CheckedChanged — Событие, которое срабатывает при изменении нажатого состояния.

ToolbarEditorItem

Элемент, позволяющий встроить редактор Eremex в панель инструментов или меню.

toolbars-get-started-ToolbarEditorItem

<mxb:Toolbar x:Name="FontToolbar" ToolbarName="Font" ShowCustomizationButton="False">
    <mxb:ToolbarEditorItem Header="Font:" EditorWidth="150" Category="Font" EditorValue="{Binding #textBox1.FontFamily, Converter={local:FontNameToFontFamilyConverter}}">
        <mxb:ToolbarEditorItem.EditorProperties>
            <mxe:ComboBoxEditorProperties ItemsSource="{Binding $parent[local:MainWindow].Fonts}" IsTextEditable="False"/>
        </mxb:ToolbarEditorItem.EditorProperties>
    </mxb:ToolbarEditorItem>
    ...
</mxb:Toolbar>

Опции ToolbarEditorItem

  • EditorValue — Позволяет вам устанавливать и считывать значение встроенного редактора.
  • EditorProperties — Указывает тип редактора, который должен быть встроен в панель инструментов/меню. В приведенном выше фрагменте кода свойству EditorProperties присвоено свойство объекта ComboBoxEditorProperties. Этот объект содержит свойства, специфичные для контрола ComboBoxEditor. Панель инструментов автоматически создаст контрол ComboBoxEditor во время выполнения программы из указанного объекта ComboBoxEditorProperties.

ToolbarTextItem

Текстовая метка. Щелчок по текстовой метке не вызывает никакого действия (команды).

toolbars-get-started-ToolbarTextItem

<mxb:Toolbar DisplayMode="StatusBar" ToolbarName="Status Bar" x:Name="StatusBar" ShowCustomizationButton="False">
    <mxb:ToolbarTextItem  Name="tbTextItem1" Alignment="Far" ShowSeparator="True" ShowBorder="False" Category="Info" CustomizationName="Position Info" Header="{Binding $parent[local:MainWindow].LineNumber}"/>
</mxb:Toolbar>

Опции ToolbarTextItem

  • SizeMode — Получает или устанавливает, будет ли размер элемента автоматически подогнан под его содержимое или растянут, чтобы занять доступное пространство на панели инструментов.
  • ShowBorder — Получает или устанавливает, следует ли отображать рамку вокруг элемента.

Другие типы элементов панели инструментов

Библиотека панелей инструментов также поддерживает другие типы элементов панели инструментов, которые не продемонстрированы в этом руководстве:

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

Смотрите следующий раздел для получения дополнительной информации: Элементы панели инструментов .

5. Создание автономной панели инструментов

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

toolbars-get-started-standalone-toolbar

Чтобы создать автономную панель инструментов, выполните следующие действия:

  1. Создайте контейнер панели инструментов (ToolbarContainerControl) в требуемой позиции. Установите для его свойства DockType значение Standalone.

    Автономные контейнеры панели инструментов не имеют границ.

  2. Добавьте панель инструментов с командами в этот контейнер панели инструментов.

Приведенный ниже код отображает автономную панель инструментов между двумя текстовыми редакторами. Команда Select All на панели инструментов выделяет текст во втором текстовом редакторе.

<mxb:ToolbarManager Name="toolbarManager1" IsWindowManager="True" >
    <Grid RowDefinitions="Auto, *, Auto, *, Auto" ColumnDefinitions="Auto, *, Auto">
        ...
        <TextBox Grid.Row="1" Grid.Column="1" x:Name="textBox1"  Text="Text Editor" AcceptsReturn="True"/>

        <mxb:ToolbarContainerControl DockType="Standalone" Grid.Row="2" Grid.Column="1">
            <mxb:Toolbar x:Name="TextEditor2Toolbar" ToolbarName="Standalone Toolbar" ShowCustomizationButton="True" AllowDragToolbar="true"  >
                <mxb:ToolbarButtonItem Header="Select All" Command="{Binding #textBox2.SelectAll}" Category="TextEditor2 Toolbar" />
                <mxb:ToolbarButtonItem Header="Make Toolbar Floating" Command="{Binding $parent[local:MainWindow].MakeToolbar2Floating}" ShowSeparator="True"
                                            Category="TextEditor2 Toolbar"/>
            </mxb:Toolbar>
        </mxb:ToolbarContainerControl>

        <TextBox x:Name="textBox2"  Grid.Row="3" Grid.Column="1" Text="Text Editor #2" AcceptsReturn="True"/>
    </Grid>
</mxb:ToolbarManager>

6. Назначение контекстного меню текстовому редактору

Чтобы указать контекстное меню для контрола, создайте объект PopupMenu и назначьте его целевому контролу, используя attached-свойство ToolbarManager.ContextPopup. Во всплывающие меню можно добавлять элементы панели инструментов любого типа.

toolbars-get-started-context-menu

<TextBox Grid.Row="1" Grid.Column="1" x:Name="textBox1"  Text="Text Editor" AcceptsReturn="True" CornerRadius="0" FontFamily="Arial" FontSize="20" >
    <mxb:ToolbarManager.ContextPopup>
        <mxb:PopupMenu ShowIconStrip="True" Header="Text Box Menu" ShowHeader="True">
            <mxb:ToolbarButtonItem Header="Undo" HotKeyDisplayString="Ctrl+Z" Command="{Binding #textBox1.Undo}" IsEnabled="{Binding #textBox1.CanUndo}"
                                    Glyph="{SvgImage 'avares://bars_sample/Images/Toolbars/EditUndo.svg'}"  Category="Edit"/>
            <mxb:ToolbarButtonItem Header="Redo" HotKeyDisplayString="Ctrl+Y"  Command="{Binding #textBox1.Redo}" IsEnabled="{Binding #textBox1.CanRedo}"
                                    Glyph="{SvgImage 'avares://bars_sample/Images/Toolbars/EditRedo.svg'}"  Category="Edit"/>
            <mxb:ToolbarSeparatorItem/>
            <mxb:ToolbarButtonItem Header="Clear" Command="{Binding #textBox1.Clear}" HotKeyDisplayString="Ctrl+Q"  Category="Edit"
                                    Glyph="{SvgImage 'avares://bars_sample/Images/Toolbars/EditDelete.svg'}"/>
        </mxb:PopupMenu>
    </mxb:ToolbarManager.ContextPopup>
</TextBox>

Опции всплывающего меню

  • ContentRightIndent — Задает ширину пустого пространства справа от текста элементов меню.

    toolbars-popupmenu-contentrightindent

  • Header — Позволяет указать заголовок меню.

  • ShowHeader — Возвращает или устанавливает, виден ли заголовок меню.

  • ShowIconStrip — Получает или устанавливает, следует ли отображать вертикальную полосу значков для элементов меню. Значок элемента меню определяется свойством Glyph элемента.

7. Назначение горячих клавиш для элементов панели инструментов

Используйте свойство ToolbarItem.HotKey, чтобы назначить элементам горячие клавиши.

<mxb:ToolbarButtonItem
    Header="Clear" Command="{Binding #textBox1.Clear}" HotKey="Ctrl+Q"
    Glyph="{SvgImage 'avares://bars_sample/Images/Toolbars/EditDelete.svg'}"  Category="Edit"/>

Границы компонента ToolbarManager определяют дефолтная область действия горячих клавиш. Если фокус находится в пределах области действия горячих клавиш, ToolbarManager может перехватывать и обрабатывать горячие клавиши. Вы можете установить для свойства ToolbarManager.IsWindowManager значение true, чтобы расширить область действия горячих клавиш на все окно. В этом случае ToolbarManager регистрирует горячие клавиши в окне и может обрабатывать горячие клавиши, даже если фокус находится за пределами ToolbarManager.

Смотрите следующий раздел для получения дополнительной информации: Горячие клавиши элемента панели инструментов .

8. Назначение всплывающих подсказок элементам панели инструментов

Свойство ToolTip позволяет вам указывать всплывающие подсказки для элементов панели инструментов.

toolbars-item-tooltip

<mxb:ToolbarButtonItem Header="Cut" Command="{Binding #textBox1.Cut}" IsEnabled="{Binding #textBox1.CanCut}"
                       Glyph="{SvgImage 'avares://bars_sample/Images/Toolbars/EditCut.svg'}"
                       Category="Edit"
                       ToolTip.Tip="Cut Selection"
                       />

9. Плавающая панель инструментов

Давайте создадим панель инструментов, плавающую в коде. Убедитесь, что у целевой панели инструментов есть имя, чтобы вы могли получить к ней доступ. После того как вы получите объект панели инструментов, установите для его свойства Toolbar.DockType значение Floating. Используйте свойство Toolbar.FloatingPosition, чтобы задать местоположение плавающей панели инструментов.

EditToolbar.DockType = Eremex.AvaloniaUI.Controls.Bars.MxToolbarDockType.Floating;
EditToolbar.FloatingPosition = new PixelPoint(200, 200);

Чтобы создать плавающую панель инструментов в XAML, определите объект Toolbar в коллекции ToolbarManager.Toolbars и задайте свойству Toolbar.DockType значение Floating.

Смотрите следующий раздел для получения дополнительной информации: Плавающие панели инструментов .

10. Время выполнения

Библиотека панелей инструментов поддерживает настройку панели инструментов пользователями во время выполнения программы. Запустите приложение, чтобы увидеть эти функции в действии:

  • Перетаскивание панелей - Панели инструментов отображают маркеры перетаскивания, которые позволяют изменять порядок расположения панелей.

toolbars-get-started-customization-drag-thumb

  • Быстрая настройка панели инструментов — вы можете быстро перемещать элементы внутри панелей и между ними с помощью перетаскивания, удерживая нажатой клавишу Alt.

toolbars-get-started-customization-with-ALT

  • Режим настройки и окно настройки — нажмите кнопку настройки на панели инструментов ("..."), а затем выберите команду "Настроить". При активации режима настройки отображается окно настройки:

toolbars-get-started-customization-window

В режиме настройки вы можете выполнить следующее:

  • Скрывайте и восстанавливайте панели инструментов.
  • Создавайте пользовательские панели инструментов и управляйте ими.
  • Скрывайте, восстанавливайте и переставляйте элементы панели инструментов между панелями и подменю.

11. Полный код

Ниже вы можете найти полный код этого руководства.

Картинки в формате SVG, используемые в этом примере, помещены в папку bars_sample/Images/Toolbars. У них для свойства Build Action установлено значение AvaloniaResource.

Главное окно.axaml:

<Window xmlns="https://github.com/avaloniaui"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
		xmlns:mxe="using:Eremex.AvaloniaUI.Controls.Editors"
        xmlns:mxb="clr-namespace:Eremex.AvaloniaUI.Controls.Bars;assembly=Eremex.Avalonia.Controls"
        
        xmlns:mxcom="clr-namespace:Eremex.AvaloniaUI.Controls.Common;assembly=Eremex.Avalonia.Controls"
        xmlns:col="using:System.Collections"
		xmlns:sys="clr-namespace:System;assembly=mscorlib"
		xmlns:local="clr-namespace:BarsSample"
        mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
        x:Class="BarsSample.MainWindow"
        Title="Toolbars Sample"
        Width="600" Height="400"
        >
    <Window.DataContext>
        <local:MainViewModel />
    </Window.DataContext>

    <mxb:ToolbarManager Name="toolbarManager1" IsWindowManager="True" >
        <Grid RowDefinitions="Auto, *, Auto, *, Auto" ColumnDefinitions="Auto, *, Auto">
            <mxb:ToolbarContainerControl DockType="Top" Grid.ColumnSpan="3">
                <mxb:Toolbar x:Name="MainMenu" ToolbarName="Main Menu" DisplayMode="MainMenu" >
                    <mxb:ToolbarMenuItem Header="File" Category="File">
                        <mxb:ToolbarButtonItem Header="New" Glyph="{SvgImage 'avares://bars_sample/Images/Toolbars/FileNew.svg'}" Category="File"
                                               Command="{Binding NewFileCommand}"/>
                        <mxb:ToolbarButtonItem Header="Open" Glyph="{SvgImage 'avares://bars_sample/Images/Toolbars/FileOpen.svg'}" Category="File"
                                               Command="{Binding OpenFileCommand}"/>
                        <mxb:ToolbarButtonItem Header="Print" Glyph="{SvgImage 'avares://bars_sample/Images/Toolbars/FilePrint.svg'}" Category="File"
                                               Command="{Binding PrintCommand}" ShowSeparator="True"/>
                    </mxb:ToolbarMenuItem>

                    <mxb:ToolbarMenuItem Header="Edit" Category="Edit" >
                        <mxb:ToolbarButtonItem Header="Cut" Glyph="{SvgImage 'avares://bars_sample/Images/Toolbars/EditCut.svg'}" Category="Edit"
                                               Command="{Binding #textBox1.Cut}" IsEnabled="{Binding #textBox1.CanCut}"
                                               />
                        <mxb:ToolbarButtonItem Header="Copy" Glyph="{SvgImage 'avares://bars_sample/Images/Toolbars/EditCopy.svg'}" Category="Edit"
                                               Command="{Binding #textBox1.Copy}" IsEnabled="{Binding #textBox1.CanCopy}"
                                               />
                        <mxb:ToolbarButtonItem Header="Paste" Glyph="{SvgImage 'avares://bars_sample/Images/Toolbars/EditPaste.svg'}" Category="Edit"
                                               Command="{Binding #textBox1.Paste}" IsEnabled="{Binding #textBox1.CanPaste}"
                                               />
                    </mxb:ToolbarMenuItem>
                    <mxb:ToolbarButtonItem Header="About" Category="Options" ShowSeparator="True" Alignment="Far" Command="{Binding AboutCommand}"/>
                </mxb:Toolbar>

                <mxb:Toolbar x:Name="EditToolbar" ToolbarName="Edit" ShowCustomizationButton="True"  >
                    <mxb:ToolbarButtonItem Header="Cut" Command="{Binding #textBox1.Cut}" IsEnabled="{Binding #textBox1.CanCut}" Glyph="{SvgImage 'avares://bars_sample/Images/Toolbars/EditCut.svg'}" Category="Edit"/>
                    <mxb:ToolbarButtonItem Header="Copy" Command="{Binding #textBox1.Copy}" IsEnabled="{Binding #textBox1.CanCopy}" Glyph="{SvgImage 'avares://bars_sample/Images/Toolbars/EditCopy.svg'}" Category="Edit"/>
                    <mxb:ToolbarButtonItem Header="Paste"
                                           Command="{Binding #textBox1.Paste}"
                                           IsEnabled="{Binding #textBox1.CanPaste}"
                                           Glyph="{SvgImage 'avares://bars_sample/Images/Toolbars/EditPaste.svg'}"
                                           Category="Edit"
                                           DropDownArrowVisibility="ShowArrow" DropDownArrowAlignment="Default"
                                           >
                        <mxb:ToolbarButtonItem.DropDownControl>
                            <mxb:PopupMenu>
                                <mxb:ToolbarButtonItem Header="Paste" Command="{Binding #textBox1.Paste}" IsEnabled="{Binding #textBox1.CanPaste}"/>
                                <mxb:ToolbarButtonItem Header="Paste As" Command="{Binding PasteAsCommand}" IsEnabled="{Binding #textBox1.CanPaste}"/>
                            </mxb:PopupMenu>
                        </mxb:ToolbarButtonItem.DropDownControl>
                    </mxb:ToolbarButtonItem>
                </mxb:Toolbar>

                <mxb:Toolbar x:Name="FontToolbar" ToolbarName="Font" ShowCustomizationButton="True" >
                    <mxb:ToolbarCheckItem Header="Bold" IsChecked="{Binding #textBox1.FontWeight, Converter={local:BoolToFontWeightConverter}, Mode=TwoWay}" Glyph="{SvgImage 'avares://bars_sample/Images/Toolbars/FontBold.svg'}" Category="Font"/>
                    <mxb:ToolbarCheckItem Header="Italic" IsChecked="{Binding #textBox1.FontStyle, Converter={local:BoolToFontStyleConverter}, Mode=TwoWay}" Glyph="{SvgImage 'avares://bars_sample/Images/Toolbars/FontItalic.svg'}" Category="Font"/>
                    <mxb:ToolbarEditorItem Header="Font:" IsVisible="" EditorWidth="150" Category="Font" EditorValue="{Binding #textBox1.FontFamily, Converter={local:FontNameToFontFamilyConverter}}">
                        <mxb:ToolbarEditorItem.EditorProperties>
                            <mxe:ComboBoxEditorProperties ItemsSource="{Binding $parent[local:MainWindow].Fonts}"
                                                IsTextEditable="False" PopupMaxHeight="145"/>
                        </mxb:ToolbarEditorItem.EditorProperties>
                    </mxb:ToolbarEditorItem>
                </mxb:Toolbar>
            </mxb:ToolbarContainerControl>


            <mxb:ToolbarContainerControl DockType="Left" Grid.Row="1" Grid.Column="0" Grid.RowSpan="3">
                <mxb:Toolbar x:Name="TextEditingToolbar" ToolbarName="Text Editing" ShowCustomizationButton="True" >
                    <mxb:ToolbarButtonItem Header="Undo" HotKeyDisplayString="Ctrl+Z" Command="{Binding #textBox1.Undo}" IsEnabled="{Binding #textBox1.CanUndo}"
                                                   Glyph="{SvgImage 'avares://bars_sample/Images/Toolbars/EditUndo.svg'}" Category="Edit"/>
                    <mxb:ToolbarButtonItem Header="Redo" HotKeyDisplayString="Ctrl+Y"  Command="{Binding #textBox1.Redo}" IsEnabled="{Binding #textBox1.CanRedo}"
                                           Glyph="{SvgImage 'avares://bars_sample/Images/Toolbars/EditRedo.svg'}"  Category="Edit"/>
                    <mxb:ToolbarButtonItem
                        Header="Clear" Command="{Binding #textBox1.Clear}" HotKey="Ctrl+Q"
                        Glyph="{SvgImage 'avares://bars_sample/Images/Toolbars/EditDelete.svg'}"  Category="Edit"/>
                </mxb:Toolbar>
            </mxb:ToolbarContainerControl>


            <TextBox Grid.Row="1" Grid.Column="1" x:Name="textBox1"  Text="Text Editor" AcceptsReturn="True" CornerRadius="0" FontFamily="Arial" FontSize="20" >
                <mxb:ToolbarManager.ContextPopup>
                    <mxb:PopupMenu ShowIconStrip="True" Header="Text Box Menu" ShowHeader="True">
                        <mxb:ToolbarButtonItem Header="Undo" HotKeyDisplayString="Ctrl+Z" Command="{Binding #textBox1.Undo}" IsEnabled="{Binding #textBox1.CanUndo}"
                                                Glyph="{SvgImage 'avares://bars_sample/Images/Toolbars/EditUndo.svg'}"  Category="Edit"/>
                        <mxb:ToolbarButtonItem Header="Redo" HotKeyDisplayString="Ctrl+Y"  Command="{Binding #textBox1.Redo}" IsEnabled="{Binding #textBox1.CanRedo}"
                                                Glyph="{SvgImage 'avares://bars_sample/Images/Toolbars/EditRedo.svg'}"  Category="Edit"/>
                        <mxb:ToolbarSeparatorItem/>
                        <mxb:ToolbarButtonItem Header="Clear" Command="{Binding #textBox1.Clear}" HotKeyDisplayString="Ctrl+Q"  Category="Edit"
                                                Glyph="{SvgImage 'avares://bars_sample/Images/Toolbars/EditDelete.svg'}"/>
                    </mxb:PopupMenu>
                </mxb:ToolbarManager.ContextPopup>
            </TextBox>

            <mxb:ToolbarContainerControl DockType="Standalone" Grid.Row="2" Grid.Column="1">
                <mxb:Toolbar x:Name="TextEditor2Toolbar" ToolbarName="Standalone Toolbar" ShowCustomizationButton="True" AllowDragToolbar="true"  >
                    <mxb:ToolbarButtonItem Header="Select All" Command="{Binding #textBox2.SelectAll}" Category="TextEditor2 Toolbar" />
                    <mxb:ToolbarButtonItem Header="Make Toolbar Floating" Command="{Binding $parent[local:MainWindow].MakeToolbar2Floating}" ShowSeparator="True"
                                               Category="TextEditor2 Toolbar"/>
                </mxb:Toolbar>
            </mxb:ToolbarContainerControl>

            <TextBox x:Name="textBox2"  Grid.Row="3" Grid.Column="1" Text="Text Editor #2" AcceptsReturn="True" CornerRadius="0" FontFamily="Arial" FontSize="20"/>


            <mxb:ToolbarContainerControl DockType="Right" Grid.Row="1" Grid.Column="2" Grid.RowSpan="3"/>


            <mxb:ToolbarContainerControl DockType="Bottom" Grid.Row="4" Grid.ColumnSpan="3">
                <mxb:Toolbar DisplayMode="StatusBar" ToolbarName="Status Bar" x:Name="StatusBar">
                    <mxb:ToolbarTextItem  Name="tbTextItem1" Alignment="Far" ShowSeparator="True" ShowBorder="False" Category="Info" CustomizationName="Position Info"
                                          Header="{Binding $parent[local:MainWindow].LineNumber}"
                                          />

                </mxb:Toolbar>
            </mxb:ToolbarContainerControl>
        </Grid>
    </mxb:ToolbarManager>
</Window>

Приложение.axaml:

<Application xmlns="https://github.com/avaloniaui"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
			 RequestedThemeVariant="Light"
             x:Class="BarsSample.App">
	<Application.Resources>
		<ResourceDictionary>
		</ResourceDictionary>
	</Application.Resources>
    <Application.Styles>
        <FluentTheme/>
		<StyleInclude Source="avares://Eremex.Avalonia.Controls/Themes/Light/Theme.axaml"/>
		<StyleInclude Source="avares://Eremex.Avalonia.Controls/Themes/Generic.axaml"/>
    </Application.Styles>
</Application>

MainWindow.axaml.cs:

using Avalonia;
using Avalonia.Controls;
using Avalonia.Media;
using CommunityToolkit.Mvvm.Input;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Runtime.CompilerServices;

namespace BarsSample
{
    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        public MainWindow()
        {
            InitializeComponent();
            textBox1.PropertyChanged += TextBox_PropertyChanged;
        }

        private void TextBox_PropertyChanged(object? sender, AvaloniaPropertyChangedEventArgs e)
        {
            if (e.Property == TextBox.CaretIndexProperty)
            {
                NotifyPropertyChanged("LineNumber");
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        IReadOnlyList<string> fonts;
        public IReadOnlyList<string> Fonts => fonts ?? (fonts = FontManager.Current.SystemFonts.Select(x => x.Name).OrderBy(x => x).ToList());

        [RelayCommand]
        public void MakeToolbar2Floating()
        {
            TextEditor2Toolbar.DockType = Eremex.AvaloniaUI.Controls.Bars.MxToolbarDockType.Floating;
            TextEditor2Toolbar.FloatingPosition = new PixelPoint(200, 200);
        }

        public string LineNumber
        {
            get
            {
                TextBox textBox = this.textBox1;
                string text = textBox.Text;
                string newLine = textBox.NewLine;

                int currentIndex = 0;
                int lineNumber = 0;
                while (currentIndex <= textBox.CaretIndex)
                {
                    lineNumber++;
                    int newLineIndex = text.IndexOf(newLine, currentIndex);
                    if (newLineIndex >= 0)
                        currentIndex = newLineIndex + newLine.Length;
                    else
                        break;
                }
                return "Line Number: " + lineNumber;
            }
        }
    }
}

MainViewModel.cs:

using Avalonia.Data.Converters;
using Avalonia.Markup.Xaml;
using Avalonia.Media;
using CommunityToolkit.Mvvm.Input;
using Eremex.AvaloniaUI.Controls.Common;
using System;
using System.Globalization;

namespace BarsSample
{
    public partial class MainViewModel : ViewModelBase
    {
        public MainViewModel()
        {
            
        }
        
        [RelayCommand]
        void About()
        {
            
        }

        [RelayCommand]
        void NewFile()
        {

        }

        [RelayCommand]
        void OpenFile()
        {

        }

        [RelayCommand]
        void Print()
        {

        }

    }


    public class BoolToFontWeightConverter : MarkupExtension, IValueConverter
    {
        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            return this;
        }

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return ((FontWeight)value) == FontWeight.Bold;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return (bool)value ? FontWeight.Bold : FontWeight.Normal;
        }
    }

    public class BoolToFontStyleConverter : MarkupExtension, IValueConverter
    {
        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            return this;
        }

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return (FontStyle)value == FontStyle.Italic;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return (bool)value ? FontStyle.Italic : FontStyle.Normal;
        }
    }

    public class FontNameToFontFamilyConverter : MarkupExtension, IValueConverter
    {
        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            return this;
        }

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return ((FontFamily)value).Name;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return new FontFamily((string)value);
        }
    }
}

Смотрите также



* Эта страница была создана автоматически с помощью сервиса машинного перевода Яндекс Переводчик.