[英]Using Blazor with Electron.NET, how can I execute code inside a component whenever I click on a MenuItem?
I am using Blazor Server.我正在使用 Blazor 服务器。 Inside my startup I am configuring the MenuItems like this:
在我的启动中,我正在像这样配置 MenuItems:
var menu = new[]
{
new MenuItem
{
Label = "File", Submenu = new[]
{
new MenuItem
{
Label = "Save",
Accelerator = "CmdOrCtrl+S",
Enabled = false,
Click = () =>
{
// How do I execute code inside my component?
},
}
}
}
};
Electron.Menu.SetApplicationMenu(menu);
My component lives on the root and is always rendered.我的组件位于根目录上并且总是被渲染。 It has a simple method called
Save
which I want to call.它有一个名为
Save
的简单方法,我想调用它。
public async Task SaveProject()
{
await Project.Save();
}
Isn't there some kind of event inside the static Electron class that I could use?我可以使用 static Electron class 中的某种事件吗? Something like
OnMenuItemClicked
.类似
OnMenuItemClicked
的东西。
Having a static property that I could access inside my component would not only be bad design, it would prevent me from accessing any instance properties.拥有可以在组件内部访问的 static 属性不仅是糟糕的设计,而且会阻止我访问任何实例属性。
I came up with a more or less applicable solution myself.我自己想出了一个或多或少适用的解决方案。 I have created a singleton service IMenuItemService which I am using in both my Startup and my Component.
我创建了一个 singleton 服务 IMenuItemService,我在我的启动和组件中都使用它。 Since MenuItems do not have an ID per se, I created a seperate Enum
MenuItemType
to seperate them.由于 MenuItems 本身没有 ID,因此我创建了一个单独的 Enum
MenuItemType
来分隔它们。 The service looks something like this:该服务看起来像这样:
public class MenuItemService : IMenuItemService
{
public Action<MenuItemType> MenuItemClicked { get; set; }
private Dictionary<MenuItemType, MenuItem> ConfigurableMenuItems { get; }
public MenuItemService()
{
ConfigurableMenuItems = new Dictionary<MenuItemType, MenuItem>();
InitializeMenuItem(MenuItemType.Close, "Close Project", null, false);
}
private void InitializeMenuItem(MenuItemType type, string label, string accelerator, bool enabled)
{
ConfigurableMenuItems.Add(type, new MenuItem
{
Label = label,
Accelerator = accelerator,
Enabled = enabled,
Click = () => { MenuItemClicked?.Invoke(type); },
});
}
public void SetEnabled(MenuItemType menuItemType)
{
ConfigurableMenuItems[menuItemType].Enabled = true;
RenderMenuItems();
}
public void SetDisabled(MenuItemType menuItemType)
{
ConfigurableMenuItems[menuItemType].Enabled = false;
RenderMenuItems();
}
public void RenderMenuItems()
{
Electron.Menu.SetApplicationMenu(new[]
{
new MenuItem
{
Label = "File", Submenu = new []
{
ConfigurableMenuItems[MenuItemType.Close]
}
}
});
}
}
With this approach I can call menuItemService.RenderMenuItems()
from anywhere in my application including Startup.cs
while in my Components I am setting the MenuItemClicked
Action in order to listen to clicks.使用这种方法,我可以从应用程序中的任何位置(包括
Startup.cs
)调用menuItemService.RenderMenuItems()
,而在我的组件中,我正在设置MenuItemClicked
操作以收听点击。
[Inject]
public IMenuItemService MenuItemService { get; set; }
private void InitializeMenuItemActions()
{
MenuItemService.SetEnabled(MenuItemType.Close);
MenuItemService.MenuItemClicked = type =>
{
if (type == MenuItemType.Close)
{
ProjectManager.CloseProject();
NavigationManager.NavigateTo("/");
}
};
}
In my case I intentionally used an Action Property instead on an EventHandler since I do not need multiple listeners for my MenuItem.在我的情况下,我故意在 EventHandler 上使用了 Action 属性,因为我的 MenuItem 不需要多个侦听器。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.