- •Лабораторная работа: События и команды в 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. Разработка простого блокнота с использованием механизма команд
- •Создание нового проекта из копии существующего
- •Краткий анализ задачи
- •Создание и привязка команд
- •Реализация логики доступности источников команд
- •Отображение позиции курсора в строке состояния
Принудительная перерисовка окна
Если внимательно посмотреть на работающее приложение, то можно заметить один неприятный нюанс. Когда по щелчку мыши вызываются диалоговые окна и они перекрывают элементы меню или кнопки, то после закрытия диалогов интерфейсные элементы не перерисовываются. Это происходит потому, что элементы теряют фокус за счет переключения на другое окно и мышь уходит (leave) с них не по установленной схеме. Как заставить окно WPF перерисоваться (paint), я так и не нашел (пока), поэтому ничего не оставалось, как применить следующий 'убогий' способ...
В файле Window1.xaml добавьте в открывающий дескриптор окна подписку на событие Activated
<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"
Closing="Window_Closing"
Activated="Window_Activated"
>
.........................................
</Window>
Создайте обработчик Window_Activated() в файле Window1.xaml .cs и заполните его так
private void Window_Activated(object sender, EventArgs e)
{
this.Height = this.ActualHeight - 1;
this.Height = this.ActualHeight + 1;
this.txtBox1.Focus();
}
Испытайте приложение - окно снизу немного дергается, но возможно пользователь этого не заметит (кто сейчас смотрит под ноги!), зато интерфейсные элементы "не залипают"
Добавление жестов
Когда мы создавали источники - элементы меню, то бодро прописали вместе с названиями задач и жесты клавиатурного ввода. Но ни один из них в настоящий момент не работает, поскольку не подкреплен соответствующим механизмом. Далее мы этот же пример повторим с применением команд, а там, мы говорили, эта функциональность уже встроена. Но на данном этапе нам такую возможность придется реализовывать вручную, и мы это сейчас выполним - для тренировки!
Добавьте к узлу текущего проекта пустой файл KeyGestures.cs
увеличить изображение
>
Заполните файл KeyGestures.cs следующим кодом
using System;
using System.Windows;
using System.Windows.Input;
using System.Collections.Generic;// Для Dictionary<TKey, TValue>
namespace Notepad1
{
partial class Window1
{ // Еще один вариант в Петцольд, WPF, с.316 !!!
// Определяем ассоциативный словарь
Dictionary<KeyGesture, RoutedEventHandler> gests =
new Dictionary<KeyGesture, RoutedEventHandler>();
void CreateGestures()
{
// File
gests.Add(new KeyGesture(Key.N, ModifierKeys.Control), NewOnExecute);//_New
gests.Add(new KeyGesture(Key.O, ModifierKeys.Control), OpenOnExecute);//_Open...
gests.Add(new KeyGesture(Key.S, ModifierKeys.Control), SaveOnExecute);//_Save
gests.Add(new KeyGesture(Key.F2, ModifierKeys.Control), PrintPreviewOnExecute);//P_rint Preview
gests.Add(new KeyGesture(Key.P, ModifierKeys.Control), PrintOnExecute);//_Print...
// Edit
gests.Add(new KeyGesture(Key.Z, ModifierKeys.Control), UndoOnExecute);//_Undo
gests.Add(new KeyGesture(Key.Y, ModifierKeys.Control), RedoOnExecute);//_Redo
gests.Add(new KeyGesture(Key.X, ModifierKeys.Control), CutOnExecute);//Cu_t
gests.Add(new KeyGesture(Key.C, ModifierKeys.Control), CopyOnExecute);//_Copy
gests.Add(new KeyGesture(Key.V, ModifierKeys.Control), PasteOnExecute);//_Paste
gests.Add(new KeyGesture(Key.Delete, ModifierKeys.None), DeleteOnExecute);//De_lete
gests.Add(new KeyGesture(Key.F, ModifierKeys.Control), FindOnExecute);//_Find...
gests.Add(new KeyGesture(Key.F3, ModifierKeys.None), FindNextOnExecute);//Find _Next
gests.Add(new KeyGesture(Key.H, ModifierKeys.Control), ReplaceOnExecute);//_Replace...
gests.Add(new KeyGesture(Key.G, ModifierKeys.Control), GoToOnExecute);//_Go To...
gests.Add(new KeyGesture(Key.A, ModifierKeys.Control), SelectAllOnExecute);//Select _All
// Format
gests.Add(new KeyGesture(Key.W, ModifierKeys.Control), WordWrapOnExecute);//_Word Wrap
}
// Перекрываем стандартный обработчик
protected override void OnPreviewKeyDown(KeyEventArgs e)
{
base.OnPreviewKeyDown(e);
// Ищем жест, останавливаем событие и исполняем обработчик
foreach (KeyGesture gest in gests.Keys)
if (gest.Matches(null, e)) // Сравниваем перехваченный жест с заданным в объекте
{
gests[gest](this, e); // Вызываем обработчик через словарь
e.Handled = true; // Останавливаем событие
break; // Прерываем цикл
}
}
}
}
Добавьте в конструктор класса Window1 файла Window1.xaml.cs вызов нашей функции создания жестов
public Window1()
{
InitializeComponent();
// Создание жестов
this.CreateGestures();
}
Запустите приложение и убедитесь, что клавиатурные жесты работают
