如何在用C#/。NET 2.0编写的Windows应用程序中实现"复制"菜单项?
我想让用户在控件中标记一些文本,然后从应用程序菜单栏中的"编辑"菜单中选择"复制"菜单项,然后在例如Excel中粘贴。
让我头疼的是如何首先确定哪个子窗体处于活动状态,然后如何找到包含应复制到剪贴板的标记文本的控件。
请帮助。
借助一些笨拙的编程对我的一位同事的帮助,我想出了这个,可以随时重构。
代码位于主窗体中。 copyToolStripMenuItem_Click方法处理"编辑"菜单中"复制"菜单项上的Click事件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| /// <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?...)
{
}
} |
要确定哪个窗口已打开,可以查询Form.ActiveMDIChild属性以获取对当前活动窗口的引用。从那里,您可以执行以下两项操作之一:
1)如果创建具有新的公共成员函数GetCopiedData()的自定义Form类(例如FormFoo),然后从该类继承应用程序的所有子窗体,则可以执行以下操作:<铅>
1
| ((FormFoo)this.ActiveMDIChild).GetCopiedData(); |
假定GetCopiedData函数将具有特定于窗体的实现,以检测应将哪些文本复制到剪贴板。
或
2)您可以使用继承来检测活动表单的类型,然后根据表单的类型执行一些操作以获取复制的数据:
1 2 3 4 5 6 7
| Form f = this.ActiveMDIChild;
if(f is FormGrid)
{
((FormGrid)f).GetGridCopiedData();
} else if(f is FormText) {
((FormText)f).GetTextCopiedData();
} |
等
那应该使您开始查找活动窗口以及如何实现复制功能。如果您需要更多从GridView复制的帮助,则最好发布另一个问题。
如果将表格设置为选项卡并且目标控件是DataGridView,则右键单击DataGridView时,有时可以使用上述方法将窗体的TabControl返回为活动控件。
我通过为DataGridView实现以下处理程序来解决此问题:-
私有无效dataGridView_CellMouseDown(对象发送者,DataGridViewCellMouseEventArgs e)
{
1 2 3 4 5 6
| if (e.Button == MouseButtons.Right)
{
dataGridView.Focus();
dataGridView.CurrentCell = dataGridView[e.ColumnIndex, e.RowIndex];
} |
} ??
为什么不扩展控件,所以控件本身提供了应该复制到剪贴板的数据。
看看ApplicationCommands文档。
在我看来,将其分解为较小的任务/问题可能会更好。
您的发音方式存在一些问题。
您打开了多个"子"窗口。这是MDI应用程序吗?
在这些子窗口之一上执行操作时,应在该窗口的事件处理程序中触发一个事件。那是您要做的第一件事。如果这是一个datagridview,我建议开始一个简单的测试。尝试捕获DataGridView.SelectionChanged事件。暂时只放入MessageBox.Show("I copied your datas!");之类的东西。
这应该使您开始,至少可以了解如何向您提出此事件。
从这里开始,我们将需要了解有关您的数据网格以及行和这些行中的子控件的更多信息。然后,我们很可能可以在渲染事件中创建事件,该事件将在适当的时间以适当的范围引发。