2008-11-14 47 views
17

我有一個簡單的WPF應用程序和一個菜單。我需要在運行時動態添加菜單項。當我簡單地創建一個新的菜單項並將其添加到其父項MenuItem中時,無論是否調用UpdateLayout,它都不會顯示在菜單中。WPF:如何在運行時將新菜單項添加到菜單中?

允許菜單在運行時動態添加其他項目時會發生什麼?

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

  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文件中定義的。我想添加額外的菜單項到這個菜單和它現有的菜單項。但是,如上所述,上面的代碼什麼都不做。

回答

20
//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); 
+0

這不適合我,反映了我已經嘗試過。我錯過了什麼?請參閱不起作用的示例文本。 – 2008-11-14 22:05:57

+0

我剛剛添加了一個新菜單,並運行了默認控件屬性的代碼,並按預期工作。我試過你的代碼,它在我的機器上工作。創建一個新項目,添加一個基本菜單並且不要調整它的任何屬性並再次嘗試你的代碼。 – Whytespot 2008-11-14 22:14:16

6

我已成功將菜單項添加到預定義的菜單項。 在以下代碼中,LanguageMenu是在xaml的設計視圖中定義的,然後在C#中添加了子項。

XAML:

<MenuItem Name="LanguageMenu" Header="_Language"> 
    <MenuItem Header="English" IsCheckable="True" Click="File_Language_Click"/> 
</MenuItem> 

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 
} 
4

我知道這是一個老的文章,但我遇到了同樣的問題。在我的情況下,問題是在XAML中,<menuitem>直接包含在<toolbar>中。一旦我將<menuitem>放入<menu>之內,它就開始工作。所以:

<toolbar> 
    <menuitem> 
    </menuitem> 
</toolbar> 

不好

<toolbar> 
    <menu> 
     <menuitem> 
     </menuitem> 
    </menu> 
</toolbar> 

-1

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(); 
0

我必須爲我打算動態創建子項目的現有項目提供名稱。此外,我遇到了我在那裏竊聽到Window_Loaded事件的問題,它運行在這之後跳出事件:

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

我必須確保我上面跑前行加載的菜單項。

這個問題可能很常見的原因是因爲intellisense推斷Items集合是「只讀」的。這個答案是部分補充的,因爲上面的答案似乎表明,如果你有先前存在的項目,你必須在代碼中刪除它們或者根本沒有它們。這是不正確的。我已經能夠得到這與預先存在的項目,並在代碼中添加額外的動態菜單項的工作:

<DataGrid AutoGenerateColumns="False" HorizontalAlignment="Stretch" Margin="12,29,12,12" Name="grid" VerticalAlignment="Stretch" Background="#FF3A81A0" AlternatingRowBackground="#FFD9EEF2" FontSize="15" RowHeaderWidth="0" KeyDown="grid_KeyDown"> 
     <DataGrid.ContextMenu> 
      <ContextMenu> 
       <MenuItem Header="_Encrypt Row Values" Click="MenuItem_ContextMenu_Click_EncryptRowValues" Name="MenuItem_EncryptRowValues" /> 
       <MenuItem Header="De_crypt Row Values" Click="MenuItem_ContextMenu_Click_DecryptRowValues" Name="MenuItem_DecryptRowValues" /> 
       <MenuItem Header="Copy Row_s" Click="MenuItem_ContextMenu_Click_CopyRows" /> 
      </ContextMenu> 
     </DataGrid.ContextMenu> 
     <DataGrid.Resources> 


      //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); 
      } 
相關問題