如何在c#/。net中实现"编辑"->"复制"菜单
如何在用C#/。NET 2.0编写的Windows应用程序中实现"复制"菜单项?
我想让用户在控件中标记一些文本,然后从应用程序菜单栏中的"编辑"菜单中选择"复制"菜单项,然后在例如Excel中粘贴。
使我头疼的是如何首先确定哪个子窗体处于活动状态,然后如何找到包含应复制到剪贴板的标记文本的控件。
请帮忙。
解决方案
回答
在我看来,将其分解为较小的任务/问题可能会更好。
发音方式存在一些问题。
我们打开了多个"子"窗口。这是MDI应用程序吗?
在这些子窗口之一上执行操作时,应在该窗口的事件处理程序中触发一个事件。那是我们要做的第一件事。如果这是一个datagridview,我建议开始一个简单的测试。尝试捕获DataGridView.SelectionChanged事件。暂时添加诸如MessageBox.Show(" I复制数据!");之类的东西。
这应该使我们开始,至少可以了解如何向我们提出该事件。
从这里,我们将需要更多地了解数据网格以及这些行中的行和子控件。然后,我们可能会在渲染事件中创建事件,这些事件将在适当的时间以适当的范围引发。
回答
为什么不扩展控件,以便控件本身提供应复制到剪贴板的数据。
看一下ApplicationCommands文档。
回答
若要确定哪个窗口是打开的,可以查询Form.ActiveMDIChild属性以获取对当前活动窗口的引用。从那里,我们可以执行以下两项操作之一:
1)如果创建自己的具有新的公共成员函数GetCopiedData()的自定义Form类(例如FormFoo),然后从该类继承应用程序的所有子窗体,则可以执行以下操作:
((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复制的帮助,最好发布另一个问题。
回答
在我的一位同事的帮助下,我和我的一位同事在进行了一些繁重的编程后,随意重构。
该代码放置在主窗体中。 copyToolStripMenuItem_Click方法处理"编辑"菜单中"复制"菜单项上的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?...) { } }
回答
如果将表单标记为选项卡,并且目标控件是DataGridView,则右键单击DataGridView时,有时可以使用上述方法将表单的TabControl作为活动控件返回。
我通过为DataGridView实现以下处理程序来解决此问题:
私有void dataGridView_CellMouseDown(对象发送者,DataGridViewCellMouseEventArgs e)
{
if (e.Button == MouseButtons.Right) { dataGridView.Focus(); dataGridView.CurrentCell = dataGridView[e.ColumnIndex, e.RowIndex]; }
}