Reputation: 989
I have a simple WPF application with a menu. I need to add menu items dynamically at runtime. When I simply create a new menu item, and add it onto its parent MenuItem, it does not display in the menu, regardless of if UpdateLayout is called.
What must happen to allow a menu to have additional items dynamically added at runtime?
Note: the following code doesn't work.
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();
At the moment, the default menu items are defined in the xaml file. I want to add additional menu items onto this menu and its existing menu items. However, as stated, the above code does nothing.
Upvotes: 25
Views: 69482
Reputation: 2171
You can let WPF enumerate a collection of models and create a sub MenuItem
for each model, e.g.
IEnumerable<RoamingDevice> devices = ...;
DevicesMenuItem.ItemsSource = devices;
Upvotes: 0
Reputation: 61
I ran into the same problem. In my case the problem was that in the XAML the <menuitem>
was directly contained in a <toolbar>
. Once I put the <menuitem>
inside a <menu>
it started working. So:
<toolbar>
<menuitem>
</menuitem>
</toolbar>
is bad
<toolbar>
<menu>
<menuitem>
</menuitem>
</menu>
</toolbar>
is good
Upvotes: 6
Reputation: 554
I did have to provide names for the existing items I intended to dynamically create sub-items for. In addition, I ran into an issue where I was tapping into the Window_Loaded event and it was jumping out of the event after running this:
row.MoveFocus(new TraversalRequest(FocusNavigationDirection.First));
I had to ensure I loaded the menu items before running the line above.
The reason this question is likely common is because intellisense infers that the Items collection is "Read-Only". This answer is partially supplemental because the answers above seem to indicate that if you have preexisting items you either have to remove them in code or not have them at all. This isn't true. I have been able to get this working with preexisting items and adding additional dynamic menu items in code:
<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);
}
Upvotes: 0
Reputation: 1
ASP.NET -> WEB Forms -> Create Menu
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();
Upvotes: -2
Reputation: 22442
I have successfully added menu items to a pre-defined menu item. In the following code, the LanguageMenu is defined in design view in th xaml, and then added the sub items in 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
}
Upvotes: 12
Reputation: 951
//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);
Upvotes: 31