Skip to content
This repository was archived by the owner on Jul 21, 2025. It is now read-only.

Commit e4d1bf0

Browse files
committed
native menu
1 parent 6fb23b3 commit e4d1bf0

File tree

2 files changed

+60
-4
lines changed

2 files changed

+60
-4
lines changed

ILSpy.Core/MainWindow.xaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@
1313
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"
1414
x:Class="ICSharpCode.ILSpy.MainWindow"
1515
>
16+
<NativeMenu.Menu>
17+
<NativeMenu>
18+
</NativeMenu>
19+
</NativeMenu.Menu>
1620
<!-- <Window.TaskbarItemInfo>
1721
<TaskbarItemInfo />
1822
</Window.TaskbarIteInfo>-->

ILSpy.Core/MainWindow.xaml.cs

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,20 @@ private void InitializeComponent()
220220

221221
TemplateApplied += MainWindow_Loaded;
222222
KeyDown += MainWindow_KeyDown;
223+
mainMenu.AttachedToVisualTree += MenuAttached;
224+
}
225+
226+
private void MenuAttached(object sender, VisualTreeAttachmentEventArgs e)
227+
{
228+
if (NativeMenu.GetIsNativeMenuExported(this) && sender is Menu mainMenu)
229+
{
230+
mainMenu.IsVisible = false;
231+
InitNativeMenu();
232+
}
233+
else
234+
{
235+
InitMainMenu();
236+
}
223237
}
224238

225239
private void MainWindow_KeyDown(object sender, KeyEventArgs e)
@@ -400,11 +414,50 @@ void InitMainMenu()
400414
mainMenu.Items = mainMenuItems;
401415
}
402416

403-
internal static string GetResourceString(string key)
417+
void InitNativeMenu()
418+
{
419+
var mainMenuCommands = App.ExportProvider.GetExports<ICommand, IMainMenuCommandMetadata>("MainMenuCommand");
420+
var mainMenuItems = NativeMenu.GetMenu(this).Items;
421+
foreach (var topLevelMenu in mainMenuCommands.OrderBy(c => c.Metadata.MenuOrder).GroupBy(c => GetResourceString(c.Metadata.Menu)))
422+
{
423+
NativeMenuItem topLevelMenuItem = mainMenuItems.OfType<NativeMenuItem>().FirstOrDefault(m => (GetResourceString(m.Header as string)) == topLevelMenu.Key);
424+
if (topLevelMenuItem == null)
425+
{
426+
topLevelMenuItem = new NativeMenuItem();
427+
topLevelMenuItem.Header = GetResourceString(topLevelMenu.Key);
428+
topLevelMenuItem.Menu = new NativeMenu();
429+
mainMenuItems.Add(topLevelMenuItem);
430+
}
431+
432+
var topLevelMenuItems = topLevelMenuItem.Menu.Items;
433+
foreach (var category in topLevelMenu.GroupBy(c => GetResourceString(c.Metadata.MenuCategory)))
434+
{
435+
if (topLevelMenuItems.Count > 0)
436+
{
437+
topLevelMenuItems.Add(new NativeMenuItemSeperator());
438+
}
439+
foreach (var entry in category)
440+
{
441+
NativeMenuItem menuItem = new NativeMenuItem();
442+
menuItem.Command = CommandWrapper.Unwrap(entry.Value);
443+
if (!string.IsNullOrEmpty(GetResourceString(entry.Metadata.Header)))
444+
menuItem.Header = GetResourceString(entry.Metadata.Header);
445+
446+
// NOTE: add icon here if Avalonia add icon support for native menu
447+
448+
menuItem.Enabled = entry.Metadata.IsEnabled;
449+
topLevelMenuItems.Add(menuItem);
450+
}
451+
}
452+
}
453+
mainMenu.Items = mainMenuItems;
454+
}
455+
456+
internal static string GetResourceString(string key)
404457
{
405458
var str = !string.IsNullOrEmpty(key)? Properties.Resources.ResourceManager.GetString(key):null;
406-
return string.IsNullOrEmpty(key)|| string.IsNullOrEmpty(str) ? key : str;
407-
}
459+
return string.IsNullOrEmpty(key) || string.IsNullOrEmpty(str) ? key : str.Replace("_", string.Empty); // avalonia menu doesn't support _ key gesture, thus remove _
460+
}
408461

409462
#endregion
410463

@@ -620,7 +673,6 @@ void MainWindow_Loaded(object sender, EventArgs e)
620673
{
621674
Application.Current.FocusManager.Focus(this);
622675

623-
InitMainMenu();
624676
InitToolbar();
625677

626678
ILSpySettings spySettings = this.spySettingsForMainWindow_Loaded;

0 commit comments

Comments
 (0)