2009-04-21 2 views
2

HI. Я расширяю приложение Windows, написанное на C#, чтобы предоставить помощь пользователю (в контексте сфокусированного элемента управления), когда они попадают в клавишу F1.Глобальный обработчик событий для всех элементов управления для справки пользователя

Что я хотел бы сделать, это использовать событие Control.HelpRequested, но я не уверен, как расширить все элементы управления для обработки этого события. http://msdn.microsoft.com/en-us/library/system.windows.forms.control.helprequested.aspx

Это на самом деле не представляется возможным обновлять каждый элемент управления «вручную», чтобы справиться с этим событием, и я действительно не нравится идея пробегаем по всем элементам управления в форме (откроется форма), чтобы связать событие обработчик.

Есть ли опрятный способ расширения всех элементов управления формы для обработки определенного события?

Это только что сделал, но я почти чувствую, что я должен быть в состоянии написать что-то вроде этого

[HandleEvent Control.HelpRequested, ApplyTo Typeof(Control)] 
void MyEventHandler(object sender, EventArgs e) 
{ 
// code to handle event... 
}

Любые предложения или, возможно, идеи о другом подходе очень ценятся - Спасибо

ответ

2

В этом примере (http://www.codeproject.com/KB/cs/ContextHelpMadeEasy.aspx) показано, как уловить ключ F1 в WndProc, а затем показать помощь только одним методом.

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

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

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

+0

На самом деле я уже прочитал эту статью и дошел до внедрения метода ProcessKeyPreview (кстати, контекст справки должен поступать напрямую из базы данных, поэтому формат файла справки окна isn 'вариант). –

+0

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

+0

Да, это предлагаемое решение, но если вы хотите запустить «глобальное» событие, вы можете запустить его из WndProc самостоятельно и иметь один обработчик событий. – Groo

0

Мне действительно не нравится идея , проходящая через все элементы управления в форме (при открытии формы), чтобы связать обработчик события.

Могу ли я спросить, почему нет?

Вы можете написать функцию, которая принимает делегат и список типов в качестве аргумента, который будет иметь тот же эффект, что и ваш «желаемый» атрибут HandleEvent.

+1

Ну это просто не чувствует себя «чистым» способом сделать это - код должен «ходить» по иерархии управления. Ваше предложение делегата, безусловно, будет работать, спасибо :) –

0

HelpRequested поддерживает механизм пузыря вверх. Он запускается для вашего активного элемента управления, и если вы не обрабатываете событие и не устанавливаете свойство Handled своего события arg arg на true, тогда он переходит в иерархию родительских элементов управления до формы.

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

Пример

Если обрабатывать HelpRequested событие формы, как показано ниже, то при нажатии F1 окно сообщения выскочит и показать имя активного управления:

private void Form1_HelpRequested(object sender, HelpEventArgs hlpevent) 
{ 
    var c = this.ActiveControl; 
    if(c!=null) 
     MessageBox.Show(c.Name); 
} 
+0

Я знаю, что это старый вопрос, но ответ может помочь будущим читателям. Странно, почему такой ответ не был представлен после почти 2500 просмотров! –

Смежные вопросы