2008-11-14 17 views
17

Tengo una aplicación WPF simple con un menú. Necesito agregar elementos de menú dinámicamente en tiempo de ejecución. Cuando simplemente creo un nuevo elemento de menú y lo agrego a su MenuItem principal, no se muestra en el menú, independientemente de si se llama a UpdateLayout.WPF: ¿Cómo se puede agregar un nuevo elemento de menú a un menú en tiempo de ejecución?

¿Qué debe pasar para permitir que un menú tenga elementos adicionales añadidos dinámicamente en el tiempo de ejecución?

Nota: el siguiente código no funciona.

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

Por el momento, los elementos de menú predeterminados se definen en el archivo xaml. Quiero agregar elementos de menú adicionales a este menú y sus elementos de menú existentes. Sin embargo, como se dijo, el código anterior no hace nada.

Respuesta

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

Esto no funciona para mí, y refleja lo que he tratado. ¿Qué me estoy perdiendo? Por favor vea el texto de ejemplo que no está funcionando. –

+0

Acabo de agregar un nuevo menú y ejecuté el código con las propiedades de control predeterminadas y funcionó como se esperaba.Probé tu código y funcionó en mi máquina. Cree un nuevo proyecto, agregue un menú básico y no ajuste ninguna de sus propiedades y pruebe su código nuevamente. – Whytespot

+4

La clave parece ser no predefinir ningún elemento del menú. Cuando los predefiní, no pude agregarlos dinámicamente. Cuando no los predefiní, pude. –

6

He agregado con éxito los elementos del menú a un elemento de menú predefinido. En el siguiente código, LanguageMenu se define en la vista de diseño en th xaml, y luego agrega los elementos secundarios en 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

Sé que esto es una entrada antigua, pero me encontré con el mismo problema. En mi caso, el problema era que en el XAML el <menuitem> estaba directamente contenido en un <toolbar>. Una vez que puse el <menuitem> dentro de un <menu>, comenzó a funcionar. Por lo tanto:

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

es malo

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

es bueno

-1

ASP.NET -> formularios web -> Crear menú

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(); 
+1

¿Por qué siente la necesidad de introducir SQL aquí? –

0

I tuve que proporcionar nombres para los artículos existentes que pretendía crear subtemas dinámicamente. Además, me encontré con un problema por el que estaba haciendo tapping en el caso Window_Loaded y estaba saltando fuera del evento después de ejecutar esto:

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

que tenía que asegurarse de que he cargado los elementos del menú antes de ejecutar la línea anterior.

El motivo por el que esta pregunta es probable es común porque intellisense infiere que la colección de elementos es "de solo lectura". Esta respuesta es parcialmente complementaria porque las respuestas anteriores parecen indicar que si tiene elementos preexistentes, debe eliminarlos en el código o no tenerlos. Esto no es verdad He sido capaz de conseguir este trabajo con elementos preexistentes y añadiendo elementos adicionales del menú dinámicos de código:

<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); 
      } 
Cuestiones relacionadas