Bug 51343 - validateMenuItem not called for menu items with c# events for the action
Summary: validateMenuItem not called for menu items with c# events for the action
Status: RESOLVED FIXED
Alias: None
Product: Xamarin.Mac
Classification: Desktop
Component: Library (Xamarin.Mac.dll) (show other bugs)
Version: 2.10.0 (C8)
Hardware: Macintosh Mac OS
: Normal normal
Target Milestone: 15.6
Assignee: Timothy Risi
URL:
Depends on:
Blocks:
 
Reported: 2017-01-10 17:30 UTC by juanjo.a
Modified: 2017-10-19 08:45 UTC (History)
5 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:


Attachments
Example on an application showing the issue. (622.63 KB, application/zip)
2017-01-11 17:24 UTC, Manuel de la Peña [MSFT]
Details


Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED FIXED

Description juanjo.a 2017-01-10 17:30:53 UTC
When in a NSMenuItem the action is defined in code using the c# event style the function validateMenuItem is never called, however if the action is defined with a selector validateMenuItem is called as expected.

menuItem1.Activated+= (sender, e) =>
{
};

menuItem2.Action = new ObjCRuntime.Selector("menuItem2Clicked");

[Export("menuItem2Clicked:")]
public void menuItem2Clicked(NSObject sender)
{
}

[Export("validateMenuItem:")]
public bool validateMenuItem(NSMenuItem menuItem)
{
//never called for menuItem1, only for menuItem2
}

The expected behavior is validateMenuItem to be called for both menu items but it seems that the native code can not find where is defined the validateMenuItem function when the c# style for the menu item action was used.
Comment 1 Manuel de la Peña [MSFT] 2017-01-11 17:23:00 UTC
Hello,

I can confirm that this is indeed a bug. Looks like the class created in the delegate by the runtime does not have the validateMenuItem: selector and it is set as the target of the NSMenuItem, I will attach a minimal example of an application showing the issue.

PS: You forgot the colon in the selector. Should have been menuItem2.Action = new ObjCRuntime.Selector("menuItem2Clicked:");
Comment 2 Manuel de la Peña [MSFT] 2017-01-11 17:24:09 UTC
Created attachment 19234 [details]
Example on an application showing the issue.

Not a great app but shows the issue.
Comment 3 Chris Hamons 2017-01-11 17:30:12 UTC
I believe the issue might be:

https://github.com/xamarin/xamarin-macios/blob/master/src/AppKit/NSMenuItem.cs#L58

Our ActionDispatcher likely doesn't have the menu selector, and it at first glance appears this API calls it on your target.

This might be painful to fix.

Until then, use the action/target "raw" APIs.
Comment 4 Tim Uy 2017-10-03 01:06:21 UTC
Hi, I just discovered this bug report after posting this on SO - https://stackoverflow.com/questions/46535458/getting-validatemenuitem-to-fire-for-nsmenuitem-using-xamarin-generated-action

In my case I am using MvvmCross to generate my menu items in my .Core cross-platform backend, and automatically generate the NSMenu. However, using this method validateMenuItems is not called. In my case I cannot directly use [Action("..")]. Any tips would be much appreciated as I am going batty looking at this.
Comment 5 Tim Uy 2017-10-03 01:09:15 UTC
Is there a clean way I can generate [Action("...")] at runtime for my class?
Comment 6 Tim Uy 2017-10-03 01:11:25 UTC
Chris, are you saying that the ActionDistpatcher needs a validateMenuItems: and that is where it would be implemented?
Comment 7 Tim Uy 2017-10-03 01:22:14 UTC
I somehow want to export the action at runtime

            foreach (var menuItem in ViewModel.ContextMenu)
            {
                var action = new ActionAttribute("lookupAction:");
                action.Action = menuItem.Command.ExecuteAsync();
                    
                var nsMenuItem = new NSMenuItem(menuItem.Title, new ObjCRuntime.Selector(action.Selector), "");


but I can't. Any tips or ideas much appreciated.
Comment 8 Tim Uy 2017-10-03 04:45:40 UTC
Just wanted to report that after I gave up on (1) using the NSMenuItem event handler and (2) making an action for every menuItem, I was able to make headway with a workaround. Use a single pre-registered action for all the menuItems, assign the NSMenuItem representedObject with a NSObject wrapped object with my commands.

See https://stackoverflow.com/questions/46535458/getting-validatemenuitem-to-fire-for-nsmenuitem-using-xamarin-generated-action/46537150#46537150
Comment 9 Manuel de la Peña [MSFT] 2017-10-11 10:04:22 UTC
Hello, this is indeed a very hard bug to fix due to the way we generate the bindings. I did point this out to the Mac OS X developers, will bring it up to them again to see if they can provide you with a nice workaround or at least confirm when will the bug be tackled.