如何在c#/.net中实现“编辑->复制”菜单

4

我该如何在使用C#/.NET 2.0编写的Windows应用程序中实现“复制”菜单项?

我希望用户可以在控件中标记一些文本,然后从应用程序菜单栏中的“编辑”菜单中选择“复制”菜单项,最后将文本粘贴到例如Excel中。

让我感到困惑的是如何首先确定哪个子窗体处于活动状态,然后如何找到包含应复制到剪贴板的标记文本的控件。

请帮帮我。


我只是想知道这些菜单项有什么用。Ctrl+C不是更好吗? - Camilo Martin
5个回答

5

在我的一位同事的帮助下,我们进行了一些重度的配对编程,并得出了以下代码,请随意进行重构。

该代码放置在主表单中。copyToolStripMenuItem_Click方法处理“编辑”菜单中“复制”菜单项的单击事件。

    /// <summary>
    /// Recursively traverse a tree of controls to find the control that has focus, if any
    /// </summary>
    /// <param name="c">The control to search, might be a control container</param>
    /// <returns>The control that either has focus or contains the control that has focus</returns>
    private Control FindFocus(Control c) 
    {
        foreach (Control k in c.Controls)
        {
            if (k.Focused)
            {
                return k;
            }
            else if (k.ContainsFocus)
            {
                return FindFocus(k);
            }
        }

        return null;
    }

    private void copyToolStripMenuItem_Click(object sender, EventArgs e)
    {
        Form f = this.ActiveMdiChild;

        // Find the control that has focus
        Control focusedControl = FindFocus(f.ActiveControl);

        // See if focusedControl is of a type that can select text/data
        if (focusedControl is TextBox)
        {
            TextBox tb = focusedControl as TextBox;
            Clipboard.SetDataObject(tb.SelectedText);
        }
        else if (focusedControl is DataGridView)
        {
            DataGridView dgv = focusedControl  as DataGridView;
            Clipboard.SetDataObject(dgv.GetClipboardContent());
        }
        else if (...more?...)
        {
        }
    }

1

为了确定哪个窗口是打开状态,可以查询Form.ActiveMDIChild属性以获得对当前活动窗口的引用。从那里,您可以执行以下两个操作之一:

1)如果您创建自己的自定义表单类(例如FormFoo),并具有一个新的公共成员函数GetCopiedData(),然后从该类继承所有应用程序的子表单,您只需执行以下操作:

((FormFoo)this.ActiveMDIChild).GetCopiedData();

假设GetCopiedData函数将具有特定于表单的实现,以便检测应复制到剪贴板的文本。

或者

2)您可以使用继承来检测活动表单的类型,然后根据表单类型执行某些操作以获取已复制的数据:

Form f = this.ActiveMDIChild;
if(f is FormGrid)
{
    ((FormGrid)f).GetGridCopiedData();
} else if(f is FormText) {
    ((FormText)f).GetTextCopiedData();
}

这应该可以帮助你开始查找活动窗口以及如何实现复制功能。如果你需要更多关于从 GridView 复制的帮助,最好发布另一个问题。


1
为什么不扩展控件,使控件本身提供应复制到剪贴板的数据。
请查看ApplicationCommands文档。

0
如果表单是选项卡式的,并且目标控件是DataGridView,则有时可以使用上述方法返回表单的TabControl作为活动控件,当右键单击DataGridView时。
我通过实现以下DataGridView处理程序来解决这个问题:- private void dataGridView_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)

{

 if (e.Button == MouseButtons.Right)
 {
      dataGridView.Focus();

      dataGridView.CurrentCell = dataGridView[e.ColumnIndex, e.RowIndex];
 }

}


-1

我觉得你最好将这个问题分解成更小的任务/问题。

从你的描述中看来,你似乎遇到了一些问题。

你打开了多个'子'窗口。这是一个MDI应用程序吗?当在子窗口之一上执行某个操作时,它应该在该窗口的事件处理程序中触发一个事件。这是你要设置的第一件事情。如果这是一个DataGridView,建议开始进行简单的测试。尝试捕获DataGridView.SelectionChanged事件。现在只需加入像MessageBox.Show("I copied your datas!");这样的内容即可。

这应该可以让你开始理解如何触发此事件。

从这里开始,我们需要更多地了解您的数据网格,以及这些行和子控件中的行。然后我们可能可以在渲染事件中创建事件,在适当的时间和范围内引发。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接