1

如果我创建“编辑->复制”菜单项并为其分配快捷键“CTRL+C”,那么我可以选择一个控件(RichTextBox、DataGridView 等)并点击“CTRL+C”然后控制本身将处理副本。我可以将文本复制出来,并将其粘贴到记事本等中。

现在,在我的整个表单中,我有很多控件。但是我有一个自定义控件,我想明确说明我为它处理复制功能。所以我在 Edit->Copy 中添加了 ShortcutKey CTRL+C,默认设置为 Enabled。

现在,我必须为该菜单项上的“单击”事件实现一个事件处理程序。如果我明确输入代码来处理副本,那么它可以工作:

public void menuEditCopy_Click(object sender, EventArgs e)
{
    myCustomControl.Copy();
}

但是,现在 Copy 不适用于任何其他类型的控件。我的第一个倾向是找出具有焦点的控件类型,并为每个控件实现一组有限的复制代码:

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...

但是,我的控件被添加到 SplitContainer,调试显示 this.ActiveControl 设置为 splitcontainer 实例,而不是控件,即使我知道该控件已被选中。

所以我最后的想法是检查每个控件是否都有焦点:

public void menuEditCopy_Click(object sender, EventArgs e)
{
    if (myCustomControl.Focused)
    {
        myCustomControl.Copy();
    }
    else if (richTextBox1.Focused)
    {
        richTextBox1.Copy();
    }
}

如果可能的话,我想避免这种情况,它有很多控件,如果我添加一个新控件,我需要更新它。有没有更好的方法来做到这一点?

谢谢

4

2 回答 2

3

A SplitContainerimplements ContainerControl,因此您可以检查其中一个并寻找它ActiveControlContainerControl是基类,所以我会这样做 - 你也可能会捕获另一种类型的容器:

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);
}
于 2009-05-08T00:10:01.793 回答
0

您可以尝试将表单的 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;
        }
    }
}

在这里,您通过将 event args Handled 属性设置为 true 来指定您已经处理了 Ctrl-C 事件。否则,如果您将其保留为 false,则每个单独的控件将照常处理 Ctrl-C 按键。

因为我们已经将 KeyPreview 设置为 true,所以表单的处理程序可以在它包含的任何其他控件之前看到每个按键,并且可以决定自己处理按键,或者允许以与表单相同的方式处理它从来没有预览过。

我认为也有必要从菜单项中删除快捷键(尽管您仍然可以手动将文本“Ctrl+C”放在菜单项名称旁边)才能正常工作,否则您的菜单项将劫持击键。

于 2009-05-08T14:56:41.823 回答