С# Динамическое добавление ToolStripMenueItems в MenuStrip

Мне было интересно, может ли SO упростить некоторую логику. У меня есть форма Windows (С# 2.0), которая содержит System.Windows.Forms.MenuStrip.

  1. Я хочу динамически добавлять ToolStripMenueItems в MenuStrip. Добавленные элементы будут удалены из базы данных (но для простоты я удалил эту часть кода ниже).
  2. Я хотел бы иметь возможность создавать сложные меню (например, Инструменты>Математика>Расчет, Справка>Документы, Справка>О программе, Формат>Кодировка>Западная, Формат>Кодировка>Другое>Греческий).

Приведенный ниже код вроде бы работает, но что бы вы сделали, чтобы функция loadToolbars() стала более эффективной/упрощенной?

Это функция, с которой мне нужна помощь:

void loadToolbars()
{
    foreach(Toolbar t in getToolStripItems())
    {
        string[] toolPath = t.toolbar.Split(">".ToCharArray(),StringSplitOptions.RemoveEmptyEntries);
        ToolStripMenuItem root = null;
        ToolStripItem[] foundItems;

        /*
         * follow the path of each Toolbar item.  If we find a dead-end,
         * add the missing part
         */
        for(int i=0; i<toolPath.Length; i++)
        {
            if(root == null)
            {
                //Search the main menu strip (System.Windows.Forms.MenuStrip)
                foundItems = DA_Menu.Items.Find(toolPath[i],false);
            }else
            {
                //Continue searching were we left off
                foundItems = root.DropDownItems.Find(toolPath[i],false);
            }

            if(foundItems.Length>0)
            {
                foreach(ToolStripItem item in foundItems)
                {
                    //Is this the Toolbar item I am looking for?
                    if(item.Text == toolPath[i])
                    {
                        if(item.OwnerItem != null && i>0)
                        {
                            if((item.OwnerItem.Text == toolPath[i-1]) 
                                && (item.Text == toolPath[i]))
                                root = (ToolStripMenuItem)item;
                        }else
                        {
                            root = (ToolStripMenuItem)item;
                        }
                    }
                }
            }else
            {
                //We hit a dead-end.  Add the missing path
                if(root == null)
                {
                    root = new ToolStripMenuItem(toolPath[i]);
                    root.Name = toolPath[i];
                    DA_Menu.Items.Add(root);
                }else
                {
                    ToolStripMenuItem tsmi = new ToolStripMenuItem(toolPath[i]);
                    tsmi.Name = toolPath[i];
                    root.DropDownItems.Add(tsmi);
                    root = tsmi;
                }
            }
        }

        //Add the Toobar item to the path that was built above
        t.Click +=new EventHandler(Toolbar_Click);
        ((ToolStripMenuItem)root).DropDownItems.Add(t);
    }
}

Все, что ниже, я доволен, но я предоставляю это, чтобы помочь другим следить за тем, что я делаю.

Эта функция управляется данными, но жестко запрограммирована в интересах SO.

private List<Toolbar> getToolStripItems()
{
   List<Toolbar>toolbars = new List<Toolbar>();

   Toolbar t = new Toolbar();
   t.Text = "Calc";
   t.path = "c:\windows\system32\calc.exe";
   t.toolbar = "Tools>Microsoft>Math";

   toolbars.Add(t);

   t = new Toolbar()
   t.Text = "Calc2";
   t.path = "c:\windows\system32\calc.exe";
   t.toolbar = "Tools>Math>Microsoft";

   toolbars.Add(t);

   return toolbars;
}

Пользовательский класс, помогающий упростить события кликов

class Toolbar:ToolStripMenuItem
{
    public string path;
    public string toolbar;
    public Toolbar()
    {
        /*
         * Set the name to the Text value
         * so that it can be found in collection
         * by key
         */
        base.Name = Text;
    }
}

Все события щелчка элемента панели инструментов будут обрабатываться в этой функции.

void Toolbar_Click(object sender, EventArgs e)
{
    //Get the Toolbar item that was clicked
    Toolbar t = (Toolbar)sender;

    //Start new process
    System.Diagnostics.Process p = new System.Diagnostics.Process();
    p.StartInfo.FileName = t.path;
    p.Start();
}

person J.Hendrix    schedule 12.10.2009    source источник


Ответы (1)


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

В противном случае измените свои данные с структуры плоского поля, такой как «Инструменты> Microsoft> Math», на что-то вроде TreeList, например. список инструментов, включая список Microsoft, включая список Math, включая записи вашего приложения. Вы даже можете построить эту структуру в базе данных.

Затем вы можете легко добавлять пункты меню рекурсивно.

person Foxfire    schedule 12.10.2009
comment
Спасибо за ваш отзыв. Это неплохая идея. Я могу рассмотреть возможность использования файла конфигурации xml для создания древовидной структуры и полного удаления базы данных... Я поиграю с этим и посмотрю, как мне нравится. Дал вам +1 за быстрый хороший ответ. - person J.Hendrix; 13.10.2009