WPF:如何在运行时向菜单添加新的menuitem?

我有一个带菜单的简单WPF应用程序。 我需要在运行时动态添加菜单项。 当我只是创建一个新的菜单项,并将其添加到其父MenuItem时,无论是否调用UpdateLayout,它都不会显示在菜单中。

允许菜单在运行时动态添加其他项目必须发生什么?

注意:以下代码不起作用。

MenuItem mi = new MenuItem(); mi.Header = "Item to add"; mi.Visibility = Visibility.Visible; //addTest is a menuitem that exists in the forms defined menu addTest.Items.Add(mi); addTest.UpdateLayout(); 

目前,默认菜单项在xaml文件中定义。 我想在此菜单及其现有菜单项中添加其他菜单项。 但是,如上所述,上面的代码什么也没做。

 //Add to main menu MenuItem newMenuItem1 = new MenuItem(); newMenuItem1.Header = "Test 123"; this.MainMenu.Items.Add(newMenuItem1); //Add to a sub item MenuItem newMenuItem2 = new MenuItem(); MenuItem newExistMenuItem = (MenuItem)this.MainMenu.Items[0]; newMenuItem2.Header = "Test 456"; newExistMenuItem.Items.Add(newMenuItem2); 

我已成功将菜单项添加到预定义的菜单项。 在下面的代码中,LanguageMenu在xaml的设计视图中定义,然后在C#中添加子项。

XAML:

    

C#:

 // Clear the existing item(s) (this will actually remove the "English" element defined in XAML) LanguageMenu.Items.Clear(); // Dynamically get flag images from a specified folder to use for definingthe menu items string[] files = Directory.GetFiles(Settings.LanguagePath, "*.png"); foreach (string imagePath in files) { // Create the new menu item MenuItem item = new MenuItem(); // Set the text of the menu item to the name of the file (removing the path and extention) item.Header = imagePath.Replace(Settings.LanguagePath, "").Replace(".png", "").Trim("\\".ToCharArray()); if (File.Exists(imagePath)) { // Create image element to set as icon on the menu element Image icon = new Image(); BitmapImage bmImage = new BitmapImage(); bmImage.BeginInit(); bmImage.UriSource = new Uri(imagePath, UriKind.Absolute); bmImage.EndInit(); icon.Source = bmImage; icon.MaxWidth = 25; item.Icon = icon; } // Hook up the event handler (in this case the method File_Language_Click handles all these menu items) item.Click += new RoutedEventHandler(File_Language_Click); // Add menu item as child to pre-defined menu item LanguageMenu.Items.Add(item); // Add menu item as child to pre-defined menu item } 

我知道这是一个老post,但我遇到了同样的问题。 在我的例子中,问题是在XAML中, 直接包含在 。 一旦我将放在

它就开始工作了。 所以:

     

不好

       

很好

我确实必须为我打算动态创建子项的现有项目提供名称。 另外,我遇​​到了一个问题,我正在点击Window_Loaded事件,它在运行之后跳出了事件:

 row.MoveFocus(new TraversalRequest(FocusNavigationDirection.First)); 

我必须确保在运行上面的行之前加载了菜单项。

这个问题很常见的原因是因为intellisense推断Items集合是“只读”的。 这个答案是部分补充的,因为上面的答案似乎表明如果你有预先存在的项目,你要么必须在代码中删除它们,要么根本没有它们。 事实并非如此。 我已经能够使用预先存在的项目并在代码中添加其他动态菜单项:

           //Add Encryption Menu Items for (int i=0; i< encryptionKeys.Count; i++) { MenuItem keyOption = new MenuItem(); keyOption.Header = "_" + i.ToString() + " " + encryptionKeys[i]; MenuItem_EncryptRowValues.Items.Add(keyOption); } //Add Decryption Menu Items for (int i = 0; i < encryptionKeys.Count; i++) { MenuItem keyOption = new MenuItem(); keyOption.Header = "_" + i.ToString() + " " + encryptionKeys[i]; MenuItem_DecryptRowValues.Items.Add(keyOption); } 

ASP.NET – > WEB表单 – >创建菜单

 CREATE TABLE `webmenu` ( `idmenu` smallint(5) NOT NULL, `submenu` smallint(5) DEFAULT NULL, `menu_title` varchar(45) DEFAULT NULL, `menu_url` varchar(45) DEFAULT NULL, `status` enum('1','0') DEFAULT '1', PRIMARY KEY (`idmenu`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; SELECT idmenu, (select menu_title from webmenu where idmenu=wm.submenu and status='1') as childmenu, menu_title, menu_url FROM tartyp.webmenu as wm where status='1' order by idmenu, submenu; 

  cmd = new MySql.Data.MySqlClient.MySqlCommand(queryStr, conn); reader = cmd.ExecuteReader(); MainMenu.Items.Clear(); while (reader.Read()) { if (reader["childmenu"] == DBNull.Value) { MenuItem homeMenuItem = new MenuItem(reader["menu_title"].ToString(), reader["menu_url"].ToString()); MainMenu.Items.Add(homeMenuItem); } else { String childmenu = reader["childmenu"].ToString(); for (int i = 0; i < MainMenu.Items.Count; i++) { if (MainMenu.Items[i].Text == childmenu) { MenuItem childMenuItem = new MenuItem(reader["menu_title"].ToString(), reader["menu_url"].ToString()); MenuItem findMenuItem = MainMenu.Items[i]; findMenuItem.ChildItems.Add(childMenuItem); break; } } } } reader.Close(); conn.Close();