- •Лабораторная работа: События и команды в 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. Разработка простого блокнота с использованием механизма команд
- •Создание нового проекта из копии существующего
- •Краткий анализ задачи
- •Создание и привязка команд
- •Реализация логики доступности источников команд
- •Отображение позиции курсора в строке состояния
Отображение позиции курсора в строке состояния
Чтобы более-менее завершить наше блокнотоподобное приложение, немного подукрасим его. Добавим в строку состояния, которая у нас имеет имя statusBar, вывод информации о положении курсора. Опять же, постараемся минимально вмешиваться в уже созданный код. Для этого все решение разместим в отдельном файле.
Выделите узел текущего проекта и добавьте командой Project/Add New Item новый файл Code File с именем CaretPosition.cs
увеличить изображение
Заполните файл CaretPosition.cs следующим кодом
using System;
using System.Windows;
using System.Windows.Controls.Primitives;
using System.Windows.Controls;
namespace Notepad2
{
// Часть класса главного окна
partial class Window1
{
// Создаем экземпляр и регистрируем обработчики
CaretPosition caretPosition;
private void CreateCaretPosition()
{
// Отображение в StatusBar номера строки и столбца
caretPosition = new CaretPosition();// Создаем объект
caretPosition.TxtBox = txtBox1; // Присоединяем TextBox
// Дополняем StatusBar
this.statusBar.Items.Add(
new System.Windows.Controls.Separator());
this.statusBar.Items.Add(caretPosition.StrLineCol);
// Увековечиваем себя!
this.statusBar.Items.Insert(0, new System.Windows.Controls.Separator());
this.statusBar.Items.Insert(0, "Снетков В.М.");
// Регистрируем обработчик события перемещения каретки
txtBox1.SelectionChanged +=
new RoutedEventHandler(txtBox1_SelectionChanged);
}
// Обработчик инициирует вычисление и отрисовку нового положения
void txtBox1_SelectionChanged(object sender, RoutedEventArgs e)
{
caretPosition.CaretChanged();
}
}
class CaretPosition
{
// Закрытые поля
StatusBarItem strLineCol = new StatusBarItem();
TextBox txtBox = new TextBox();
// Открытые свойства
// Для добавления в строку состояния клиента
public StatusBarItem StrLineCol // Папа '-->'
{
// Только для чтения
get { return strLineCol; }
}
// Для присоединения к TextBox клиента
public TextBox TxtBox // Мама '>--'
{
// Только для записи
set { txtBox = value; }
}
// Вычисляет номер строки
int GetLine()
{
int count = 0;
int pos = 0;
int caretPos = txtBox.SelectionStart + 1; //txtBox1.CaretIndex
while (pos < caretPos)
{
count++; // Счетчик строк
pos = txtBox.Text.IndexOf("\r\n", pos);// \n - перевод строки
if (pos != -1) // Нашли очередную пару
pos += 2; // Сдвигаемся правее найденных
else
break;// Больше нет
}
return count;
}
public void CaretChanged()
{
if (!txtBox.IsFocused)
return;
int posChar = txtBox.CaretIndex;
int line = GetLine();
int column = posChar - txtBox.GetCharacterIndexFromLineIndex(line - 1) + 1;
// Обновляем в строке состояния
strLineCol.Content = String.Format(" Ln {0} \t Col {1}", line, column);
}
}
}
В файле Window1.xaml.cs добавьте в конструктор класса Window1 код вызова функции CreateCaretPosition()
public Window1()
{
InitializeComponent();
// Создание жестов
this.CreateGestures();
// Дополнительные обработчики в файле EnabledControls.cs
AdditionalHandlers();
// Отображение в StatusBar номера строки и столбца
// Функция находится в файле CaretPosition.cs
CreateCaretPosition();
}
Запустите приложение - номера строк и столбцов отображаются. Поэкспериментируйте с функциональностью, разберитесь с кодом
Обратите внимание, как мы из вновь созданного класса CaretPosition подключились (мама) через свойство TxtBox к существующему объект txtBox1 окна и извлекаем нужную информацию уже в новом классе. И как созданный в новом классе элемент строки состояния подключили (папа) обратно к окну. Получился как бы канал связи, по которому информация из объекта txtBox1 окна поступает в экземпляр нового класса, а затем в обработанном виде возвращается обратно в окно для отображения в объекте statusBar.
Снимок блокнота на данный момент будет таким
увеличить изображение
Видно, что строки и столбцы теперь отображаются в строке состояния, как и ФИО. Имейте ввиду, что мы изначально приняли тезис, что завернутые строки Word Wrap считаем продолжением одной и той же строки и позицию каретки отображаем как в длинной незавернутой строке.
