If I do not create an "Edit->Copy" menu item and assign it the shortcut keys "CTRL+C", then I can select a control (RichTextBox, DataGridView, etc..) and hit "CTRL+C" and the control itself will handle the copy. I can copy text out, and paste it into notepad, etc..
如果我没有创建“编辑 - >复制”菜单项并为其分配快捷键“CTRL + C”,那么我可以选择一个控件(RichTextBox,DataGridView等)并点击“CTRL + C”并且控件本身将处理副本。我可以复制文本,并将其粘贴到记事本等。
Now throughout my whole form, I have a lot of controls. But I have a custom control that I want to make clear that I handle Copy functionality for. So I added the ShortcutKey CTRL+C to Edit->Copy, and by default it is set to Enabled.
现在,在整个表单中,我有很多控件。但我有一个自定义控件,我想明确我处理复制功能。所以我将ShortcutKey CTRL + C添加到Edit-> Copy,默认情况下它设置为Enabled。
Now, I have to implement an event handler for the 'click' event on that menu item. If I explicitly put in code to handle the copy, then it works:
现在,我必须为该菜单项上的“click”事件实现一个事件处理程序。如果我明确地输入代码来处理副本,那么它的工作原理如下:
public void menuEditCopy_Click(object sender, EventArgs e)
{
myCustomControl.Copy();
}
However, now Copy does not work on any other type of control. My first inclination was to find out the type of control that has focus, and implement a limited set of copy code for each of them:
但是,现在复制不适用于任何其他类型的控件。我的第一个倾向是找出具有焦点的控件类型,并为每个控件实现一组有限的复制代码:
public void menuEditCopy_Click(object sender, EventArgs e)
{
if (this.ActiveControl is MyCustomControl)
{
((MyCustomControl)this.ActiveControl).Copy();
}
else if (this.ActiveControl is RichTextBox)
{
((RichTextBox)this.ActiveControl).Copy();
}
}
etc...
However, my controls are added to a SplitContainer, and debugging shows that this.ActiveControl is set to the splitcontainer instance, not the control, even though I know that control is selected.
但是,我的控件被添加到SplitContainer,并且调试显示this.ActiveControl设置为splitcontainer实例,而不是控件,即使我知道该控件已被选中。
So my last thought is to literally check if every control has focus:
所以我最后的想法是逐字检查每个控件是否有焦点:
public void menuEditCopy_Click(object sender, EventArgs e)
{
if (myCustomControl.Focused)
{
myCustomControl.Copy();
}
else if (richTextBox1.Focused)
{
richTextBox1.Copy();
}
}
I would like to avoid this if possible, it is a lot of controls, and if I add a new control, I would need to update it. Is there a better way of doing this?
我想尽可能避免这种情况,这是很多控件,如果我添加一个新的控件,我需要更新它。有更好的方法吗?
Thanks
2 个解决方案
#1
A SplitContainer
implements ContainerControl
, so you could check for either one and look for it's ActiveControl
instead. ContainerControl
is the base class, so I would go for that - you might catch another type of container as well:
SplitContainer实现了ContainerControl,因此您可以检查其中任何一个并查找它的ActiveControl。 ContainerControl是基类,所以我会这样做 - 你也可以捕获另一种类型的容器:
private void DoCopy(Control control)
{
if(control is ContainerControl)
DoCopy(control.SelectedControl);
else if(control is MyCustomControl)
((MyCustomControl)control).Copy();
else if(control is RichTextBox)
((RichTextBox)control).Copy();
else
throw new NotSupportedException("The selected control can't copy!");
}
void menuEditCopy_Click(object sender, EventArgs e)
{
DoCopy(this.ActiveControl);
}
#2
You could try settting the KeyPreview property of your form to true. Then you could set up a handler for the form's KeyDown event which would look like the following:
您可以尝试将表单的KeyPreview属性设置为true。然后你可以为表单的KeyDown事件设置一个处理程序,如下所示:
private void Form_KeyDown(object sender, KeyEventArgs e)
{
if(e.Modifiers == Keys.Control && e.KeyCode == Keys.C)
{
if (ActiveControl.GetType() == typeof(MyCustomControl))
{
((MyCustomControl)ActiveControl).Copy();
e.Handled = true;
}
}
}
Here you are specifying that you have handled the Ctrl-C event by setting the event args Handled property to true. Else, if you leave it as false, the Ctrl-C key press will be handled as per usual by each individual control.
在这里,您通过将event args Handled属性设置为true来指定已处理Ctrl-C事件。否则,如果将其保留为false,则按每个单独的控件按常规处理Ctrl-C键。
Because we have set the KeyPreview to true the form's handler gets to see each key press before any other control that it contains and can decide to deal with the key press itself or else allow it to be handled in the same way as if the form had never previewed it.
因为我们已经将KeyPreview设置为true,所以表单的处理程序可以在其包含的任何其他控件之前看到每个按键,并且可以决定处理按键本身,或者允许以与表单具有相同的方式处理它。从未预览过它。
I think as well it would be necessary to remove the short-cut key from your menu item (although you could still manually put the text "Ctrl+C" next to your menu item name) for this to work, otherwise your menu item will hijack the key stroke.
我认为有必要从你的菜单项中删除快捷键(尽管你仍然可以手动将文本“Ctrl + C”放在菜单项名称旁边),这样就可以了,否则你的菜单项就会劫持关键的一击。
#1
A SplitContainer
implements ContainerControl
, so you could check for either one and look for it's ActiveControl
instead. ContainerControl
is the base class, so I would go for that - you might catch another type of container as well:
SplitContainer实现了ContainerControl,因此您可以检查其中任何一个并查找它的ActiveControl。 ContainerControl是基类,所以我会这样做 - 你也可以捕获另一种类型的容器:
private void DoCopy(Control control)
{
if(control is ContainerControl)
DoCopy(control.SelectedControl);
else if(control is MyCustomControl)
((MyCustomControl)control).Copy();
else if(control is RichTextBox)
((RichTextBox)control).Copy();
else
throw new NotSupportedException("The selected control can't copy!");
}
void menuEditCopy_Click(object sender, EventArgs e)
{
DoCopy(this.ActiveControl);
}
#2
You could try settting the KeyPreview property of your form to true. Then you could set up a handler for the form's KeyDown event which would look like the following:
您可以尝试将表单的KeyPreview属性设置为true。然后你可以为表单的KeyDown事件设置一个处理程序,如下所示:
private void Form_KeyDown(object sender, KeyEventArgs e)
{
if(e.Modifiers == Keys.Control && e.KeyCode == Keys.C)
{
if (ActiveControl.GetType() == typeof(MyCustomControl))
{
((MyCustomControl)ActiveControl).Copy();
e.Handled = true;
}
}
}
Here you are specifying that you have handled the Ctrl-C event by setting the event args Handled property to true. Else, if you leave it as false, the Ctrl-C key press will be handled as per usual by each individual control.
在这里,您通过将event args Handled属性设置为true来指定已处理Ctrl-C事件。否则,如果将其保留为false,则按每个单独的控件按常规处理Ctrl-C键。
Because we have set the KeyPreview to true the form's handler gets to see each key press before any other control that it contains and can decide to deal with the key press itself or else allow it to be handled in the same way as if the form had never previewed it.
因为我们已经将KeyPreview设置为true,所以表单的处理程序可以在其包含的任何其他控件之前看到每个按键,并且可以决定处理按键本身,或者允许以与表单具有相同的方式处理它。从未预览过它。
I think as well it would be necessary to remove the short-cut key from your menu item (although you could still manually put the text "Ctrl+C" next to your menu item name) for this to work, otherwise your menu item will hijack the key stroke.
我认为有必要从你的菜单项中删除快捷键(尽管你仍然可以手动将文本“Ctrl + C”放在菜单项名称旁边),这样就可以了,否则你的菜单项就会劫持关键的一击。