用户帮助的所有控件的全局事件处理程序

时间:2022-12-14 15:52:29

HI, I'm extending a windows application written in C# to provide help to the user (in the context of the focused control) when they hit the F1 key.

嗨,我正在扩展一个用C#编写的Windows应用程序,以便在用户点击F1键时为用户提供帮助(在聚焦控件的上下文中)。

What I’d like to do is make use of the Control.HelpRequested event but I’m not sure how to extend all the controls to handle this event. http://msdn.microsoft.com/en-us/library/system.windows.forms.control.helprequested.aspx

我想要做的是使用Control.HelpRequested事件,但我不知道如何扩展所有控件来处理此事件。 http://msdn.microsoft.com/en-us/library/system.windows.forms.control.helprequested.aspx

It’s not really feasible to update each control “by hand” to handle this event and I really don’t like the idea of looping through all the controls in a form (as the form opens) to associate the event handler.

使用“手动”更新每个控件以处理此事件并不是真的可行,我真的不喜欢循环遍历表单中的所有控件(如表单打开)以关联事件处理程序的想法。

Is there a neat way to extend all controls of a form to handle a specific event?

是否有一种简洁的方法来扩展表单的所有控件来处理特定事件?

This is just made up but i almost feel like i should be able to write something like this

这只是弥补,但我几乎觉得我应该能够写出这样的东西

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

Any suggestions or perhaps ideas on a different approach are much appreciated - Thanks

任何关于不同方法的建议或想法都非常感谢 - 谢谢

3 个解决方案

#1


This example (http://www.codeproject.com/KB/cs/ContextHelpMadeEasy.aspx) shows how to trap the F1 key in WndProc and then show the help from one method only.

此示例(http://www.codeproject.com/KB/cs/ContextHelpMadeEasy.aspx)显示如何在WndProc中捕获F1键,然后仅显示一种方法的帮助。

The idea in that article is to implement an interface exposing control's ID and then show context help based on that id. The F1 handler then checks if your control implements that interface, and if not, then it check's the control's parent until it finds an implementation of that interface.

该文章的想法是实现一个暴露控件ID的接口,然后根据该id显示上下文帮助。然后,F1处理程序检查您的控件是否实现了该接口,如果没有,则检查控件的父级,直到找到该接口的实现。

But an even simpler approach (if you don't want to add an ID to each control) is to modify the F1 handler to show context help based on a static type dictionary (e.g. Dictionary), which would contain Topic IDs for every supported control. So, whenever you need to associate a topic with a specified control, you would update the dictionary.

但更简单的方法(如果您不想为每个控件添加ID)是修改F1处理程序以显示基于静态类型字典(例如Dictionary)的上下文帮助,该字典将包含每个支持的控件的主题ID 。因此,只要您需要将主题与指定控件相关联,就可以更新字典。

Again, it would be wiser to add more abstraction to this approach by adding some sort of a provider (delegate or interface) to that dictionary. For example, you might need additional logic to show topics based on control's type, name, or some other property.

同样,通过向该字典添加某种提供者(委托或接口)来为这种方法添加更多抽象会更明智。例如,您可能需要其他逻辑来根据控件的类型,名称或其他属性显示主题。

#2


I really don’t like the idea of looping through all the controls in a form (as the form opens) to associate the event handler.

我真的不喜欢循环遍历表单中的所有控件(如表单打开)以关联事件处理程序的想法。

Can I ask why not?

我可以问为什么不呢?

You could write a function that takes a delegate and a list of types as an arguement, which will have exactly the same effect as your "wished for" HandleEvent attribute.

你可以编写一个函数,它将一个委托和一个类型列表作为一个争论,它将与你的“希望”HandleEvent属性具有完全相同的效果。

#3


The HelpRequested supports bubble up mechanism. It fires for your active control and if you don't handle the event and not set Handled property of its event arg to true, then it bubbles up to the parent control hierarchy up to form.

HelpRequested支持冒泡机制。它会激活您的主动控件,如果您不处理该事件并且未将其事件arg的Handled属性设置为true,则它会向上形成父控件层次结构。

So it's enough to handle your HelpRequested of your form and then, you can decide about the help you want to show, based on active control of the form or its parent hierarchy.

因此,只需处理表单的HelpRequested即可,然后,您可以根据对表单或其父层次结构的主动控制来决定要显示的帮助。

Example

If you handle HelpRequested event of the form like below, then when you press F1 a message box will pop up and show name of active control:

如果您处理如下表单的HelpRequested事件,那么当您按F1时,将弹出一个消息框并显示活动控件的名称:

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

#1


This example (http://www.codeproject.com/KB/cs/ContextHelpMadeEasy.aspx) shows how to trap the F1 key in WndProc and then show the help from one method only.

此示例(http://www.codeproject.com/KB/cs/ContextHelpMadeEasy.aspx)显示如何在WndProc中捕获F1键,然后仅显示一种方法的帮助。

The idea in that article is to implement an interface exposing control's ID and then show context help based on that id. The F1 handler then checks if your control implements that interface, and if not, then it check's the control's parent until it finds an implementation of that interface.

该文章的想法是实现一个暴露控件ID的接口,然后根据该id显示上下文帮助。然后,F1处理程序检查您的控件是否实现了该接口,如果没有,则检查控件的父级,直到找到该接口的实现。

But an even simpler approach (if you don't want to add an ID to each control) is to modify the F1 handler to show context help based on a static type dictionary (e.g. Dictionary), which would contain Topic IDs for every supported control. So, whenever you need to associate a topic with a specified control, you would update the dictionary.

但更简单的方法(如果您不想为每个控件添加ID)是修改F1处理程序以显示基于静态类型字典(例如Dictionary)的上下文帮助,该字典将包含每个支持的控件的主题ID 。因此,只要您需要将主题与指定控件相关联,就可以更新字典。

Again, it would be wiser to add more abstraction to this approach by adding some sort of a provider (delegate or interface) to that dictionary. For example, you might need additional logic to show topics based on control's type, name, or some other property.

同样,通过向该字典添加某种提供者(委托或接口)来为这种方法添加更多抽象会更明智。例如,您可能需要其他逻辑来根据控件的类型,名称或其他属性显示主题。

#2


I really don’t like the idea of looping through all the controls in a form (as the form opens) to associate the event handler.

我真的不喜欢循环遍历表单中的所有控件(如表单打开)以关联事件处理程序的想法。

Can I ask why not?

我可以问为什么不呢?

You could write a function that takes a delegate and a list of types as an arguement, which will have exactly the same effect as your "wished for" HandleEvent attribute.

你可以编写一个函数,它将一个委托和一个类型列表作为一个争论,它将与你的“希望”HandleEvent属性具有完全相同的效果。

#3


The HelpRequested supports bubble up mechanism. It fires for your active control and if you don't handle the event and not set Handled property of its event arg to true, then it bubbles up to the parent control hierarchy up to form.

HelpRequested支持冒泡机制。它会激活您的主动控件,如果您不处理该事件并且未将其事件arg的Handled属性设置为true,则它会向上形成父控件层次结构。

So it's enough to handle your HelpRequested of your form and then, you can decide about the help you want to show, based on active control of the form or its parent hierarchy.

因此,只需处理表单的HelpRequested即可,然后,您可以根据对表单或其父层次结构的主动控制来决定要显示的帮助。

Example

If you handle HelpRequested event of the form like below, then when you press F1 a message box will pop up and show name of active control:

如果您处理如下表单的HelpRequested事件,那么当您按F1时,将弹出一个消息框并显示活动控件的名称:

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