ToolStripMenuItem для нескольких ContextMenuStrip - PullRequest
2 голосов
/ 29 ноября 2011

У меня есть форма, которая содержит панель вкладок с множеством страниц. Каждый из них имеет свое собственное контекстное меню (отображается правой кнопкой мыши). Но если я добавлю ToolStripMenuItem в несколько ContextMenuStrips, только последний элемент меню действительно будет иметь этот элемент меню. Простой пример кода:

    ToolStripMenuItem tim_refresh = new ToolStripMenuItem("Refresh", null, (o, e) =>
        {
            MessageBox.Show("Refresh");
        });

    ContextMenuStrip cms1 = new ContextMenuStrip();
    cms1.Items.Add(tim_refresh);

    ContextMenuStrip cms2 = new ContextMenuStrip();
    cms2.Items.Add(tim_refresh);

    this.tblDataManagerObjects.ContextMenuStrip = cms1;
    this.tblDataSourceTypes.ContextMenuStrip = cms2;

Если кто-то покажет эти меню одно за другим, сначала будет пусто ... Как мне добиться того, чего я хочу?

Ответы [ 2 ]

1 голос
/ 18 декабря 2013

одно контекстное меню отображается один раз за раз; вам, вероятно, не нужно много клонов везде, но вы можете захотеть переместить один единственный экземпляр ваших пунктов меню в полосу меню в тот момент, когда полоса меню открывается;

Я перемещаю сюда элементы именованного (великого) родителя в дочернее (открывающееся в настоящее время) меню, когда локальная копия пуста, и все следующие открытия ctx я просто добавляю, что перемещает «расположенные» три элемента меню из ранее открытый ctxMenuStrip к текущему открывающему:

    // /4429368/toolstripmenuitem-dlya-neskolkih-contextmenustrip
    // http://stackoverflow.com/questions/6275120/toolstripmenuitem-added-to-several-places?rq=1
    // WILL_ADD_PARENT_MENU_ITEMS_IN_Opening first time opened we locate common menu items from GrandParent, then we move them to the current slider; cool?
    private static ToolStripItem[] separatorLoadSave = null;
    private void contextMenuStrip1_Opening(object sender, CancelEventArgs e) {
        if (separatorLoadSave == null) {
            separatorLoadSave = new ToolStripItem[3];

            Control slidersAutoGrow = base.Parent;
            if (base.Parent.Name != "SlidersAutoGrow") return;
            Control slidersForm = slidersAutoGrow.Parent;
            if (slidersForm.Name != "SlidersForm") return;

            ToolStripItem[] separator = slidersForm.ContextMenuStrip.Items.Find("toolStripSeparator1", false);
            if (separator.Length > 0) separatorLoadSave[0] = separator[0];

            ToolStripItem[] load = slidersForm.ContextMenuStrip.Items.Find("mniParameterSetLoad", false);
            if (load.Length > 0) separatorLoadSave[1] = load[0];

            ToolStripItem[] save = slidersForm.ContextMenuStrip.Items.Find("mniParameterSetSave", false);
            if (save.Length > 0) separatorLoadSave[2] = save[0];
        }

        this.contextMenuStrip1.SuspendLayout();
        this.contextMenuStrip1.Items.AddRange(separatorLoadSave);
        this.contextMenuStrip1.ResumeLayout();
    }
1 голос
/ 29 ноября 2011

Это потому, что визуал не может быть потомком нескольких разных визуалов одновременно. В вашем случае tim_refresh является потомком cms1 и cms2 одновременно.

Вам необходимо создать два совершенно отдельных экземпляра ToolStripMenuItem.

EDIT:

Вы можете извлечь визуальное создание в методе фактора, чтобы упростить создание нескольких объектов:

private ToolStripMenuItem CreateToolStripMenuItem(string name)
{
   return new ToolStripMenuItem(name, null, (o, e) =>
        {
            MessageBox.Show(name);
        });
}

// then just call it once per each menu strip
ContextMenuStrip cms1 = new ContextMenuStrip();
cms1.Items.Add(CreateToolStripMenuItem("Refresh"));

ContextMenuStrip cms2 = new ContextMenuStrip();
cms2.Items.Add(CreateToolStripMenuItem("Refresh"));
...