Я хотел бы добавить дополнительные пункты меню в свое контекстное меню. В идеале элементы включаются с помощью validateMenuItem:
[Action("validateMenuItem:")]
public bool ValidateMenuItem(NSMenuItem item)
{
_logger.DebugFormat("Validating {0} menu item with Action {1}", item.Title, item.Action.Name);
var target = item.Target;
var menuItem = ViewModel.ContextMenu.Where(x => x.Title == item.Title).FirstOrDefault();
if (menuItem != null) {
return menuItem.Command.CanExecute();
}
return false;
}
на https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/MenuList/Articles/EnablingMenuItems.html. Если я вручную создам действие, оно будет вызвано, но если я назначу обработчик событий следующим образом:
var nsMenuItem = new NSMenuItem(menuItem.Title,
(sender, e) =>
{
menuItem.Command.ExecuteAsync();
});
nsMenuItem.Target = this;
validateMenuItem: не вызывается. Действие, назначенное с помощью этого метода, — __monomac_internal_ActionDispatcher_activated: from https://github.com/xamarin/xamarin-macios/blob/master/src/AppKit/ActionDispatcher.cs (помогите мне, пожалуйста, Рольф Бьярне Квинге). Поскольку у меня нет этого действия в моем классе (я думаю), validateMenuItem никогда не вызывается, и мой пункт меню никогда не активируется. Как я могу заставить это работать?
Обновить. Если я добавлю это в свой контроллер представления,
[Action("__monomac_internal_ActionDispatcher_activated:")]
public void MonomacInternalAction(NSObject sender)
{
}
validateMenuItem: вызывается для новых элементов. Однако обработчик события заменяется этой функцией. (Эта проблема может быть неразрешима!) Это может быть проблема экспорта или действия - я вижу
const string skey = "__monomac_internal_ActionDispatcher_activated:";
[Preserve, Export (skey)]
public void OnActivated (NSObject sender)
{
EventHandler handler = Activated;
if (handler != null)
handler (sender, EventArgs.Empty);
}
Обновление 2. только что нашел https://bugzilla.xamarin.com/show_bug.cgi?id=51343
Обновление 3. Я могу обмануть validateMenuItem с помощью
public override bool RespondsToSelector(ObjCRuntime.Selector sel)
{
if (sel.Name.Contains("__monomac_internal_ActionDispatcher_activated")) {
return true;
}
return base.RespondsToSelector(sel);
}
теперь, если бы я только мог найти способ вызвать исходное событие!