C# - 将 ContextMenuStrip 项目复制到另一个
C# - Duplicate ContextMenuStrip Items into another
我在 Windows 表单应用程序中有两个 ContextMenuStrip,其中一个有 3 个项目,另一个有 none.
让我们假设:
ContextMenuStrip c1 = new ContextMenuStrip();
ContextMenuStrip c2;
c1 有 3 个 ToolStripMenuItems
,c2 是 ContextMenuStrip
应该复制 c1 项目的目的地。
我试着写这个:
c2 = new ContextMenuStrip(c1.Container);
但它给了我一个 ArgumentNullException
因为 c1.Container
等于 null
.
我不知道如何解决这个问题,你能帮我吗?
Ps。
我会 new ToolStripMenuItem
(s),没有参考文献
和
while
或 foreach
循环解决方案不是执行此操作的最佳方法。
谢谢:)
您需要创建一个新的 ContextMenuStrip
并将 Item
(不是 c1
的 Container
添加到新菜单中:
c2 = new ContextMenuStrip();
c2.Items.AddRange(c1.Items);
但请注意,这不会重复 项目。 相同的项目实例 现在在两个菜单中。
如果要克隆它们,这会相当复杂,因为您必须处理项目的特定类型、要克隆的属性,尤其是事件处理程序。
一个简单的例子可以是:
c2.Items.AddRange(c1.Items.OfType<ToolStripItem>()
.Select(item => new ToolStripMenuItem(item.Text))
.OfType<ToolStripItem>().ToArray());
第二个 OfType
是必要的,以避免从 ToolStripMenuItem[]
到 ToolStripItem[]
的协变数组转换,这是 AddRange()
所期望的。
附带说明:Container
是 包含 菜单的组件(这就是为什么 null
当菜单未显示时)而不是菜单保留其项目的东西。
然后,创建一个创建 ContextMenuStrip 的函数,并在每次需要新菜单时调用它
Func<ContextMenuStrip> newContextMenuStrip = () => {
var c = new ContextMenuStrip();
c.Items.Add("item 1");
c.Items.Add("item 2");
c.Items.Add("item 3");
return c;
};
var c1 = newContextMenuStrip();
var c2 = newContextMenuStrip();
晚会迟到了,但我过去遇到过同样的问题并找到了一个相当简单的解决方案。
假设您的 toolStripMenuItem 在上下文菜单中声明为 'TSMI_open',
您可以在上下文菜单打开时有效地对其进行热交换。
像这样:
void Context1_Opening(object sender, CancelEventArgs e)
{
Context1.Items.Insert(0, TSMI_open);
}
void Context2_Opening(object sender, CancelEventArgs e)
{
Context2.Items.Insert(0, TSMI_open);
}
菜单项无缝出现在两个菜单上,连续打开同一个菜单两次不会出错。
我在 Windows 表单应用程序中有两个 ContextMenuStrip,其中一个有 3 个项目,另一个有 none.
让我们假设:
ContextMenuStrip c1 = new ContextMenuStrip();
ContextMenuStrip c2;
c1 有 3 个 ToolStripMenuItems
,c2 是 ContextMenuStrip
应该复制 c1 项目的目的地。
我试着写这个:
c2 = new ContextMenuStrip(c1.Container);
但它给了我一个 ArgumentNullException
因为 c1.Container
等于 null
.
我不知道如何解决这个问题,你能帮我吗?
Ps。
我会 new ToolStripMenuItem
(s),没有参考文献
和
while
或 foreach
循环解决方案不是执行此操作的最佳方法。
谢谢:)
您需要创建一个新的 ContextMenuStrip
并将 Item
(不是 c1
的 Container
添加到新菜单中:
c2 = new ContextMenuStrip();
c2.Items.AddRange(c1.Items);
但请注意,这不会重复 项目。 相同的项目实例 现在在两个菜单中。
如果要克隆它们,这会相当复杂,因为您必须处理项目的特定类型、要克隆的属性,尤其是事件处理程序。
一个简单的例子可以是:
c2.Items.AddRange(c1.Items.OfType<ToolStripItem>()
.Select(item => new ToolStripMenuItem(item.Text))
.OfType<ToolStripItem>().ToArray());
第二个 OfType
是必要的,以避免从 ToolStripMenuItem[]
到 ToolStripItem[]
的协变数组转换,这是 AddRange()
所期望的。
附带说明:Container
是 包含 菜单的组件(这就是为什么 null
当菜单未显示时)而不是菜单保留其项目的东西。
然后,创建一个创建 ContextMenuStrip 的函数,并在每次需要新菜单时调用它
Func<ContextMenuStrip> newContextMenuStrip = () => {
var c = new ContextMenuStrip();
c.Items.Add("item 1");
c.Items.Add("item 2");
c.Items.Add("item 3");
return c;
};
var c1 = newContextMenuStrip();
var c2 = newContextMenuStrip();
晚会迟到了,但我过去遇到过同样的问题并找到了一个相当简单的解决方案。
假设您的 toolStripMenuItem 在上下文菜单中声明为 'TSMI_open', 您可以在上下文菜单打开时有效地对其进行热交换。 像这样:
void Context1_Opening(object sender, CancelEventArgs e)
{
Context1.Items.Insert(0, TSMI_open);
}
void Context2_Opening(object sender, CancelEventArgs e)
{
Context2.Items.Insert(0, TSMI_open);
}
菜单项无缝出现在两个菜单上,连续打开同一个菜单两次不会出错。