Форма поиска банка Primer. Часть 6. Обработка событий клавиатуры

2022, Feb 23    

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

Предыдущие статьи серии:

Часть 1. Готовим макет формы

Часть 2. Организуем контроль правильности ввода

Часть 3. Добавляем диалоговые окна

Часть 4. Диалоговое окно с деревом

Часть 5. Фильтрация по стажу

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

Горячие клавиши для редактирования списков

Начнем с того, что позволим открывать диалоговые окна для выбора значений полей txtEducation, txtCareer и txtAddress с помощью стандартной для Кроноса комбинации клавиш Ctrl+F2. Одновременно определим комбинацию клавиш Ctrl+Del для быстрой очистки поля и сброса всех соответствующих поисковых ограничений.

Создадим обработчики события KeyDown для этих полей:

function txtEducation_KeyDown( event )
	if event.Key == Keys.F2 and event.CtrlPressed then
		event.Handled = true
		btnEducation_Click(Me.btnEducation)
	elseif event.Key == Keys.Delete and event.CtrlPressed then
		event.Handled = true
		Me.txtEducation.Text = ""
		education = {}
	end
end

function txtCareer_KeyDown( event )
	if event.Key == Keys.F2 and event.CtrlPressed then
		event.Handled = true
		btnCareer_Click(Me.btnCareer)
	elseif event.Key == Keys.Delete and event.CtrlPressed then
		event.Handled = true
		Me.txtCareer.Text = ""
		career = {}
	end
end

function txtAddress_KeyDown( event )
	if event.Key == Keys.F2 and event.CtrlPressed then
		event.Handled = true
		btnAddress_Click(Me.btnAddress)
	elseif event.Key == Keys.Delete and event.CtrlPressed then
		event.Handled = true
		Me.txtAddress.Text = ""
		address = {}
	end
end

Горячая клавиша для выполнения операции поиска

Теперь разрешим запускать процесс поиска записей с помощью комбинации клавиш Ctrl+F.

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

function Форма_KeyPreview( event )

Чтобы не запустить поиск дважды, нам необходимо различать, произошло нажатие клавиши или ее отпускание. Определить это можно по значению свойства Type объекта event, переданного обработчику в качестве параметра. В нашем случае при нажатии этой свойство будет содержать значение FormKeyEvent.Pressed, а при отпускании FormKeyEvent.Released.

	if event.Key == Keys.F and event.CtrlPressed and event.Type == event.Pressed then

После того, наш обработчик отработает, событие клавиатуры будет передано в элемент формы, на котором находился фокус ввода. Чтобы это предотвратить присвоим true свойству Handled объекта event.

Конечно, поля нашей формы сами не реагируют на Ctrl+F, а значит даже если мы ничего не присвоим event.Handled и не прекратим обработку события ничего особенного не произойдет, но для выработки полезной привычки, лучше выполнять такое присваивание во всех случаях.

	event.Handled = true

Далее мы устанавливаем фокус ввода на кнопку btnFind. Это необходимо для того, чтобы отработал обработчик события TypeValidationCompleted в полях возраста и стажа. Если помните, этот обработчик выполнял необходимую коррекцию введенных значений.

	Me.btnFind.Focused = true

И, наконец, имитируем щелчок по кнопке btnFind, вызывая обработчик события Click:

	btnFind_Click(Me.btnFind)

Листинг обработчика Форма_KeyPreview:

function Форма_KeyPreview( event )
	if event.Key == Keys.F and event.CtrlPressed and 
		event.Type == event.Pressed then
		event.Handled = true
		Me.btnFind.Focused = true
		btnFind_Click(Me.btnFind)
	end
end

Реализуем спинер для числовых полей

Реализуем также в полях txtAgeFrom, txtAgeTo и txtExperience, подобие компонента SpinButton, позволяющего изменять значение числового поля нажатием клавиш “стрелка вверх” и “стрелка вниз”.

Вновь будем использовать событие KeyDown, а сам обработчик оформим отдельной функцией AgeKeyDown, которую свяжем с событием в функции Форма_Load:

function Форма_Load ( form, event )
...
--	Контроль ввода (стаж и возраст)
	local age_ctrl = {Me.txtAgeFrom, Me.txtAgeTo, Me.txtExperience }
	for _, ctrl in pairs(age_ctrl) do
...
		ctrl.KeyDown = AgeKeyDown
	end
end	

В самом обработчике первым делом вызовем AgeValidation, чтобы откорректировать значение и привести его к виду числа. Если в результате значением поля окажется пустая строка, запишем в него ноль. В противном случае будем увеличивать или уменьшать значение на единицу (если нажата стрелка без клавиш-модификаторов) или на 10 (если одновременно нажата клавиша Shift):

function AgeKeyDown( event )
--	спинер для возраста
	if event.Key == Keys.Up or event.Key == Keys.Down then
		AgeValidation(event)
		event.Control.Text = event.Control.Text:trim()
		if event.Control.Text == "" then
			event.Control.Text = 0
			event.Handled = true
			return
		end	
		local val = tonumber(event.Control.Text) 
		if val and event.Key == Keys.Up and event.ShiftPressed then
			event.Control.Text = val + 10
		elseif val and event.Key == Keys.Up then
			event.Control.Text = val + 1
		elseif val and event.Key == Keys.Down and val > 10 and event.ShiftPressed then
			event.Control.Text = val - 10
		elseif val and event.Key == Keys.Down and val > 0 then
			event.Control.Text = val - 1
		end	
		event.Handled = true
		return
	end	
end

Заключение

На этом, пожалуй, наш демонстрационный проект можно завершить. Хотя …

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

И все же остановимся здесь.

Все материалы можно посмотреть и скачать здесь.

Страница создана на основе шаблона flexible-jekyll