动态克隆ToolStripMenuItem到ContexMenuStrip c#Winforms

时间:2017-08-29 20:53:36

标签: c# winforms

我有一个工作 ToolStripMeniItem 菜单。

我还创建了 ContextMenuStrip 并将其分配给 PictureBox

我想将 ToolStripMeniItem 中的项目克隆/复制到 ContextMenuStrip

我有以下代码:

    this.components = new System.ComponentModel.Container();
    this.pbxPhoto = new System.Windows.Forms.PictureBox();
    this.menuView = new System.Windows.Forms.ToolStripMenuItem();
    this.ctxMenuView = new System.Windows.Forms.ContextMenuStrip(this.components);

    this.menuView.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
    this.menuImage});
    this.menuView.Name = "menuView";
    this.menuView.Size = new System.Drawing.Size(53, 24);
    this.menuView.Text = "&View";

    this.menuImage.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
    this.menuStretch,
    this.menuActual});
    this.menuImage.Name = "menuImage";
    this.menuImage.Size = new System.Drawing.Size(126, 26);
    this.menuImage.Text = "&Image";
    this.menuImage.DropDownOpening += new System.EventHandler(this.menuImage_DropDownOpening);

    private PictureBoxSizeMode[] modeMenuArray =
    {
            PictureBoxSizeMode.StretchImage,
            PictureBoxSizeMode.Normal
    };
    private int _selectedImageMode = 0;


    private void menuImage_DropDownOpening(object sender, EventArgs e)
    {
        if(sender is ToolStripMenuItem)
        {
            bool bImageLoaded = (pbxPhoto.Image != null);

            foreach (ToolStripMenuItem mi in ((ToolStripMenuItem)sender).DropDownItems)
            {
                mi.Enabled = bImageLoaded;
                mi.Checked = (this._selectedImageMode == mi.MergeIndex);
            }
        }
    }

    private void menuImage_ChildClick(object sender, EventArgs e)
    {
        if (sender is ToolStripMenuItem)
        {
            ToolStripMenuItem mi = (ToolStripMenuItem)sender;

            _selectedImageMode = mi.MergeIndex;
            pbxPhoto.SizeMode = modeMenuArray[mi.MergeIndex];

            pbxPhoto.Invalidate();
        }
    }

    private void DefineContextMenu()
    {
        foreach(ToolStripMenuItem mi in menuView.DropDownItems)
        {
            //ctxMenuView.Items.Add(mi.Name); // Debug 1 
            ctxMenuView.Items.Add(mi);
        }
    }

出于调试目的,如果我使用Debug 1注释行,代码工作正常: enter image description here

如果我使用上面的代码,我收到一个错误: enter image description here

在“:”之后表示:该集合已被修改;枚举操作可能无法执行。

我可以在我的代码中执行什么操作(函数 DefineContextMenu()),以便将ToolStripMenuItems的内容传输到我的ContextMenuStrip?

2 个答案:

答案 0 :(得分:0)

我刚刚找到了解决方案。关键是首先创建一个 ContextMenuStrip ,然后将其分配给 ToolStripMenuItem DropDown 属性。

关键代码如下:

menuView.DropDown = ctxMenuView;

这是因为, ContextMenuStrip 类基于 ToolStripDropDown 类,并定义Items属性以容纳 ToolStripItem 实例的集合; ToolsStripMenuItem 对象基于 ToolStripDropDownItem 类,该类定义了一个 DropDown 属性,该属性包含 ToolsStripDropDown 实例。 / p>

答案 1 :(得分:0)

这可能有一天会帮助某人。我还意识到,尝试将项目添加到ContextMenu.Items会更改原始集合(实际上是从原始集合中删除了该项目)。使用AddRange方法对我有用。因为它需要一个ToolStripItems数组,所以我只是将每个DropDownItem复制到一个数组中,然后将该数组传递给AddRange方法。您仍然必须将contextMenu添加到menuView.DropDown才能起作用。

private void DefineContextMenu()
    {
        ToolStripItem[] toolArr = new ToolStripItem[menuView.DropDownItems.Count];
        int count = 0;
        foreach(ToolStripItem t in menuView.DropDownItems)
        {
            toolArr[count] = t;
            count++;
        }
        ctxtMenuView.Items.AddRange(toolArr);
        menuView.DropDown = ctxtMenuView;

    }