WPF:如何在运行时将新菜单项添加到菜单中?
问题描述:
我有一个简单的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文件中定义的。我想添加额外的菜单项到这个菜单和它现有的菜单项。但是,如上所述,上面的代码什么都不做。
答
//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:
<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
}
答
我知道这是一个老的文章,但我遇到了同样的问题。在我的情况下,问题是在XAML中,<menuitem>
直接包含在<toolbar>
中。一旦我将<menuitem>
放入<menu>
之内,它就开始工作。所以:
<toolbar>
<menuitem>
</menuitem>
</toolbar>
不好
<toolbar>
<menu>
<menuitem>
</menuitem>
</menu>
</toolbar>
好
答
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();
答
我必须为我打算动态创建子项目的现有项目提供名称。此外,我遇到了我在那里窃听到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);
}
这不适合我,反映了我已经尝试过。我错过了什么?请参阅不起作用的示例文本。 – 2008-11-14 22:05:57
我刚刚添加了一个新菜单,并运行了默认控件属性的代码,并按预期工作。我试过你的代码,它在我的机器上工作。创建一个新项目,添加一个基本菜单并且不要调整它的任何属性并再次尝试你的代码。 – Whytespot 2008-11-14 22:14:16