- •Лабораторная работа: События и команды в wpf
- •Обзор библиотечных событий
- •Упражнение 1. Обработка событий клавиатуры
- •События мыши
- •Упражнение 2. Прослушивание событий мыши
- •Упражнение 3. Создание и прослушивание пользовательского события
- •Обработчики уровня класса
- •Добавление информации в объект аргумента события
- •Задание для Упражнения 3
- •Модель команд
- •Объекты команд
- •Библиотечные классы команд
- •Присоединение команды к источнику
- •Привязка команды к прослушивающему элементу
- •Упражнение 4. Привязка команд в разметке
- •Перекрытие функций диспетчеризации событий
- •Прямой вызов команд
- •Упражнение 5. Привязка команд в процедурном коде
- •Жесты как источники команд
- •Добавление жестов в команду
- •Способ 1
- •Способ 2
- •Способ 3
- •Добавление жестов в прослушивающий элемент
- •Упражнение 6. Разработка простого блокнота без механизма команд
- •Создание главного меню
- •Добавление иконок
- •Создание логических ресурсов
- •Создание панели инструментов, строки состояния и рабочей области
- •Замена встроенного контекстного меню
- •Назначение ресурсов неразделяемыми
- •Замена иконок на прозрачные
- •Отключение встроенных команд
- •Подключение иконки приложения
- •Распределение класса по нескольким файлам и создание вспомогательных функций
- •Размещение вариантов заголовков окна в ресурсах приложения
- •Создание заготовок обработчиков
- •Регистрация обработчиков в разметке
- •Реализация обработчиков раздела меню File
- •Обработка системной кнопки
- •Реализация части обработчиков раздела меню Edit
- •Разработка и кодирование диалогового окна Find and Replace
- •Кодирование функциональности Find and Replace в основном окне
- •Подключение функциональности Find and Replace к источникам задач
- •Разработка диалогового окна Go To
- •Применение вложенных ресурсов
- •Подключение функциональности Go To к основному окну
- •Прочие задачи
- •Принудительная перерисовка окна
- •Добавление жестов
- •Логика отключения источников задач
- •Реализация логики отключения источников задачи Save
- •Упражнение 7. Разработка простого блокнота с использованием механизма команд
- •Создание нового проекта из копии существующего
- •Краткий анализ задачи
- •Создание и привязка команд
- •Реализация логики доступности источников команд
- •Отображение позиции курсора в строке состояния
Регистрация обработчиков в разметке
Мы подготовили интерфейс окна Window1 и дальше наступает этап кодирования функциональности. В окне Window1 мы откажемся от услуг механизма команд, а будем использовать обычную технологию, основанную на обработчиках событий. Начнем постепенно подключать обработчики к источникам задач, используя событие Click.
Подключите декларативно в файле разметки Window1.xaml к каждому источнику события Click соответствующий обработчик и назначьте имена элементам для последующего управления ими из кода
Обратите внимание на некоторую некорректность работы подсказчика кода IntelliSense, который не предлагает нам список уже созданных обработчиков. Он ищет их в застраничном файле Window1.xaml.cs, в то время как обработчики находятся в других файлах частичного класса. В данном случае это не слишком большое неудобство, поскольку мнемоника составления имен у нас строго соблюдена и мы вряд ли ошибемся. Но в больших практических проектах это следует иметь ввиду, прежде чем разбивать класс окна по отдельным файлам.
Разметка с подключенными обработчиками и присвоенными именами будет выглядеть так (файл приводится целиком)
<Window x:Class="Notepad1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1: Управление состоянием источников команд"
Width="500" Height="375"
MinWidth="500" MinHeight="375"
WindowStartupLocation="CenterScreen"
ResizeMode="CanResizeWithGrip"
Loaded="Window_Loaded"
Icon="Notepad.ico"
>
<Window.Resources>
<!-- File -->
<Image x:Shared="False" x:Key="iconNew" Source="Images/NewDocumentHS.png" Width="16" Height="16" />
<Image x:Shared="False" x:Key="iconOpen" Source="Images/OpenHS.png" Width="16" Height="16" />
<Image x:Shared="False" x:Key="iconSave" Source="Images/SaveHS.png" Width="16" Height="16" />
<Image x:Shared="False" x:Key="iconPageSetup" Source="Images/PrintSetupHS.png" Width="16" Height="16" />
<Image x:Shared="False" x:Key="iconPrintPreview" Source="Images/PrintPreviewHS.png" Width="16" Height="16" />
<Image x:Shared="False" x:Key="iconPrint" Source="Images/PrintHS.png" Width="16" Height="16" />
<!-- Edit -->
<Image x:Shared="False" x:Key="iconUndo" Source="Images/Edit_UndoHS.png" Width="16" Height="16" />
<Image x:Shared="False" x:Key="iconRedo" Source="Images/Edit_RedoHS.png" Width="16" Height="16" />
<Image x:Shared="False" x:Key="iconCut" Source="Images/CutHS.png" Width="16" Height="16" />
<Image x:Shared="False" x:Key="iconCopy" Source="Images/CopyHS.png" Width="16" Height="16" />
<Image x:Shared="False" x:Key="iconPaste" Source="Images/PasteHS.png" Width="16" Height="16" />
<Image x:Shared="False" x:Key="iconDelete" Source="Images/DeleteHS.png" Width="16" Height="16" />
<Image x:Shared="False" x:Key="iconFind" Source="Images/FindHS.png" Width="16" Height="16" />
<Image x:Shared="False" x:Key="iconFont" Source="Images/FontHS.png" Width="16" Height="16" />
</Window.Resources>
<DockPanel LastChildFill="True">
<!-- Меню -->
<Menu DockPanel.Dock="Top">
<MenuItem Header="_File">
<!-- Сокращенные варианты подключения иконок с использованием статических ресурсов -->
<MenuItem Name="itemNew" Click="NewOnExecute" Header="_New" InputGestureText="Ctrl+N"
Icon="{StaticResource iconNew}" />
<MenuItem Name="itemOpen" Click="OpenOnExecute" Header="_Open..." InputGestureText="Ctrl+O"
Icon="{StaticResource iconOpen}" />
<MenuItem Name="itemSave" Click="SaveOnExecute" Header="_Save" InputGestureText="Ctrl+S"
Icon="{StaticResource iconSave}" />
<MenuItem Name="itemSaveAs" Click="SaveAsOnExecute" Header="Save _As..." />
<Separator />
<MenuItem Name="itemPageSetup" Click="PageSetupOnExecute"
Header="Page Set_up..." Icon="{StaticResource iconPageSetup}" />
<MenuItem Name="itemPrintPreview" Click="PrintPreviewOnExecute" Header="P_rint Preview"
InputGestureText="Ctrl+F2" Icon="{StaticResource iconPrintPreview}" />
<MenuItem Name="itemPrint" Click="PrintOnExecute"
Header="_Print..." InputGestureText="Ctrl+P" Icon="{StaticResource iconPrint}" />
<Separator />
<MenuItem Name="itemExit" Click="ExitOnExecute" Header="E_xit" />
</MenuItem>
<MenuItem Header="_Edit">
<MenuItem Name="itemUndo" Click="UndoOnExecute"
Header="_Undo" InputGestureText="Ctrl+Z" Icon="{StaticResource iconUndo}" />
<MenuItem Name="itemRedo" Click="RedoOnExecute"
Header="_Redo" InputGestureText="Ctrl+Y" Icon="{StaticResource iconRedo}" />
<Separator></Separator>
<MenuItem Name="itemCut" Click="CutOnExecute"
Header="Cu_t" InputGestureText="Ctrl+X" Icon="{StaticResource iconCut}" />
<MenuItem Name="itemCopy" Click="CopyOnExecute"
Header="_Copy" InputGestureText="Ctrl+C" Icon="{StaticResource iconCopy}" />
<MenuItem Name="itemPaste" Click="PasteOnExecute"
Header="_Paste" InputGestureText="Ctrl+V" Icon="{StaticResource iconPaste}" />
<MenuItem Name="itemDelete" Click="DeleteOnExecute"
Header="De_lete" InputGestureText="Del" Icon="{StaticResource iconDelete}" />
<Separator></Separator>
<MenuItem Name="itemFind" Click="FindOnExecute"
Header="_Find..." InputGestureText="Ctrl+F" Icon="{StaticResource iconFind}" />
<MenuItem Name="itemFindNext" Click="FindNextOnExecute"
Header="Find _Next" InputGestureText="F3" />
<MenuItem Name="itemReplace" Click="ReplaceOnExecute"
Header="_Replace..." InputGestureText="Ctrl+H" />
<MenuItem Name="itemGoTo" Click="GoToOnExecute"
Header="_Go To..." InputGestureText="Ctrl+G" />
<Separator></Separator>
<MenuItem Name="itemSelectAll" Click="SelectAllOnExecute"
Header="Select _All" InputGestureText="Ctrl+A" />
</MenuItem>
<MenuItem Header="F_ormat">
<MenuItem Name="itemFont" Click="FontOnExecute"
Header="_Font..." Icon="{StaticResource iconFont}" />
<Separator />
<MenuItem Name="itemWordWrap" Click="WordWrapOnExecute"
Header="_Word Wrap" IsCheckable="True" IsChecked="True" InputGestureText="Ctrl+W" />
</MenuItem>
<MenuItem Header="_Help">
<MenuItem Name="itemAbout" Click="AboutOnExecute"
Header="_About" />
</MenuItem>
</Menu>
<!-- Панель инструментов -->
<ToolBarTray DockPanel.Dock="Top">
<ToolBar>
<Button Name="btnNew" Click="NewOnExecute" Width="23" Content="{StaticResource iconNew}" />
<Button Name="btnOpen" Click="OpenOnExecute" Width="23" Content="{StaticResource iconOpen}" />
<Button Name="btnSave" Click="SaveOnExecute" Width="23" Content="{StaticResource iconSave}" />
</ToolBar>
<ToolBar>
<Button Name="btnUndo" Click="UndoOnExecute" Width="23" Content="{StaticResource iconUndo}" />
<Button Name="btnRedo" Click="RedoOnExecute" Width="23" Content="{StaticResource iconRedo}" />
<Separator />
<Button Name="btnCut" Click="CutOnExecute" Width="23" Content="{StaticResource iconCut}" />
<Button Name="btnCopy" Click="CopyOnExecute" Width="23" Content="{StaticResource iconCopy}" />
<Button Name="btnPaste" Click="PasteOnExecute" Width="23" Content="{StaticResource iconPaste}" />
<Button Name="btnDelete" Click="DeleteOnExecute" Width="23" Content="{StaticResource iconDelete}" />
</ToolBar>
<ToolBar Header="Find:">
<TextBox Width="100" />
<Button Name="btnFind" Click="FindOnExecute" Width="23" Content="{StaticResource iconFind}" />
</ToolBar>
</ToolBarTray>
<!-- Строка состояния -->
<StatusBar DockPanel.Dock="Bottom" Height="32" Name="statusBar">
<Label>Simulator Application is Loading</Label>
<Separator />
<ProgressBar Height="20" Width="100" IsIndeterminate="True" />
</StatusBar>
<!-- Многострочное текстовое поле редактирования -->
<TextBox TextWrapping="Wrap"
AcceptsReturn="True"
AcceptsTab="True"
VerticalScrollBarVisibility="Auto"
Name="txtBox1"
>
<TextBox.ContextMenu>
<ContextMenu Width="100">
<MenuItem Name="contextCut" Click="CutOnExecute"
Header="Cu_t" Icon="{StaticResource iconCut}" />
<MenuItem Name="contextCopy" Click="CopyOnExecute"
Header="_Copy" Icon="{StaticResource iconCopy}" />
<MenuItem Name="contextPaste" Click="PasteOnExecute"
Header="_Paste" Icon="{StaticResource iconPaste}" />
<MenuItem Name="contextDelete" Click="DeleteOnExecute"
Header="De_lete" Icon="{StaticResource iconDelete}" />
</ContextMenu>
</TextBox.ContextMenu>
</TextBox>
</DockPanel>
</Window>
Столько имен нам не понадобиться, но для единообразия мы, на всякий случай, промаркировали все источники задач (может пригодится).
Запустите приложение для проверки отсутствия синтаксических ошибок
Следующим шагом следует наполнить созданные заготовки обработчиков практическим кодом в соответствии с логикой работы приложения. Поскольку наша задача состоит не в создании полнофункционального приложения целиком, а в иллюстрации технологии его создания с применением механизма команд, реализуем намеченные задачи частично. Некоторые функции, ввиду их большого объема и сложности кодирования, мы только обозначим выдачей соответствующих диалоговых окон или сообщений. Управление доступностью элементов-источников задач пользовательского интерфейса пока отложим 'на потом' (или навсегда!).
