C # Динамически добавлять ToolStripMenueItems в MenuStrip - PullRequest
1 голос
/ 12 октября 2009

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

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

Кажется, что приведенный ниже код работает, но что бы вы сделали, чтобы сделать 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();
}

1 Ответ

1 голос
/ 12 октября 2009

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

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

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

...