Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Общие вопросы по .NET и C# > Динамическое создание элементов контекстного меню


Автор: ajunta 12.9.2008, 15:20
Привет!

Идея задачи такая - есть много объектов на форме, для каждого из которых должно быть доступно контекстное меню. Причеи элементы жэтого меню - для каждого свои. Точнее так - есть набор элементов меню, характерный для всех, и в довесок к нему нужно создать еще элементов.

На простом примере пытаюсь реализовать это так:

в contextMenuStrip1 дизайн-тайм создал характерные для всех элементы,
а contextMenuStrip2 повесил как общий компанент для контекстного меню, далее:

Код

        private void contextMenuStrip2_Opening(object sender, CancelEventArgs e)
        {
            contextMenuStrip2.Items.Clear(); //очищение преыддузего состояниея
//дополнение текущего списка характерными элементами
            for (int i=0; i<contextMenuStrip1.Items.Count;i++)
            {
                contextMenuStrip2.Items.Add(contextMenuStrip1.Items[i]);
            }
//добалвение индивидуальных элементов
            for (int i=0; i<4;i++)
            {
                contextMenuStrip2.Items.Add("Hello ! "+i.ToString());
            }
        }


так вот это работает только один раз, а потом помсле 
contextMenuStrip2.Items.Clear(); элементов не остается ни в contextMenuStrip2, ни в contextMenuStrip1. И при следубющем клике видны только индивидуальные элементы, а общие потеряны.

что я делаю не так?

Автор: Dennnis 12.9.2008, 16:45
Вот этим
Код

            for (int i=0; i<contextMenuStrip1.Items.Count;i++)
            {
                contextMenuStrip2.Items.Add(contextMenuStrip1.Items[i]);
            }
ты ПЕРЕМЕЩАЕШЬ все элементы меню из contextMenuStrip1 в contextMenuStrip2.
Вот этим
Цитата(ajunta @  12.9.2008,  15:20 Найти цитируемый пост)
 contextMenuStrip2.Items.Clear(); 
ты их удаляешь.
После этого у тебя нет элементов ни в contextMenuStrip1 ни в contextMenuStrip2.

Добавлено через 6 минут и 18 секунд
Вместо contextMenuStrip2.Items.Clear() воспользуйся contextMenuStrip2.Items.RemoveAt(int index), и удаляй только динамически созданные элементы.

Автор: Wanderer2019 12.9.2008, 17:36
ajunta
какой то не совсем удачный способ. Уж лучше в XML хранить список меню для конкретного объекта.

Автор: Bishop 13.9.2008, 15:29
ajunta, я бы сразу заполнил меню всеми пунктами, а при его раскрытии скрывал ненужные. Простейшая реализация:
Код
// флаги отображения
enum ShowOpt
{
    Button = 1,
    TextBox = 2,
    ListBox = 4
}
// общие пункты contextMenuStrip1 созданы в design time
private void FormMain_Load(object sender, EventArgs e)
{
    // назначаем меню
    button1.ContextMenuStrip = listBox1.ContextMenuStrip = contextMenuStrip1;
    // задаём контролам флаги тех пунктов, которые хотим на них видеть
    button1.Tag = ShowOpt.Button;
    listBox1.Tag = ShowOpt.ListBox;
    // создаём зависимые пункты меню и присваиваем им флаги отображения
    contextMenuStrip1.Items.Add("Button").Tag = ShowOpt.Button | ShowOpt.TextBox; // а этот пункт будет показываться для двух классов
    contextMenuStrip1.Items.Add("ListBox").Tag = ShowOpt.ListBox;
    // понятно, что всё это нужно делать не вручную
}

private void contextMenuStrip1_Opening(object sender, System.ComponentModel.CancelEventArgs e)
{
    // проходимся по всем пунктам меню
    foreach (ToolStripItem item in contextMenuStrip1.Items)
    {
        if (item.Tag != null) // пустой у общих пунктов
        {
            // проверяем совпадение масок, результат проверки -> видимость пункта
            item.Visible = ((ShowOpt)item.Tag & (ShowOpt)(sender as ContextMenuStrip).SourceControl.Tag) > 0;
        }
    }
}


Автор: ajunta 15.9.2008, 09:41
Спасибо!, разобрался! Удалять дополтные элементы действиетльно проще smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)