Forum Xamarin.Mac

Get tag of button that activated popup menu

Dutch2Dutch2 Member ✭✭

I have an application that has several buttons that use the same right click menu.

How do I know which button the user right clicked on?

Below sample code creates a menu and two buttons.

````
public override void ViewDidLoad()
{
base.ViewDidLoad();

        NSMenu menu = new NSMenu();
        NSMenuItem menuItem = new NSMenuItem("Test");
        menuItem.Activated += menuClicked;
        menu.AddItem(menuItem);

        NSButton button1 = new NSButton();
        button1.Title = "Button1";
        button1.Tag = 1;
        button1.SetFrameSize(new CGSize(100, 22));
        button1.SetFrameOrigin(new CGPoint(10, 10));
        button1.Menu = menu;
        View.AddSubview(button1);

        NSButton button2 = new NSButton();
        button2.Title = "Button2";
        button2.Tag = 1;
        button2.SetFrameSize(new CGSize(100, 22));
        button2.SetFrameOrigin(new CGPoint(10, 40));
        button2.Menu = menu;
        View.AddSubview(button2);
    }

    private void menuClicked(object sender, EventArgs e)
    {
        Console.WriteLine("Menu clicked - which button popped up the menu?");
    }

```

Thanks in advance!

Best Answer

  • ColeXColeX Member, Xamarin Team Xamurai
    edited December 2020 Accepted Answer

    We right click on the button to show the pop up menu , so that we can detect it in right-click event of the Button .

    First ,we need to create new subclass NSButton, and then override RightMouseDown method .

    Detect when right click on the button

    public class MyButton : NSButton
        {
    
            public override void RightMouseDown(NSEvent theEvent)
            {
                nint tag = this.Tag;  //get which button 
            }
        }
    
    

    Detect when click on the menuItem

    public class MyButton : NSButton
        {
    
            public delegate void MyHandler(object sender,EventArgs e);
            public event MyHandler myHandler;
    
            public override void RightMouseDown(NSEvent theEvent)
            {
                myHandler(this,null);
            }
        }
    
        public partial class ViewController : NSViewController
        {
            public ViewController(IntPtr handle) : base(handle)
            {
            }
    
            int index = 0;
    
            public override void ViewDidLoad()
            {
                base.ViewDidLoad();
    
                // Do any additional setup after loading the view.
    
    
                NSMenu menu = new NSMenu();
                NSMenuItem menuItem = new NSMenuItem("Test");
                menuItem.Activated += menuClicked;
                menu.AddItem(menuItem);
    
                MyButton button1 = new MyButton();
                button1.Title = "Button1";
                button1.Tag = 1;
                button1.SetFrameSize(new CGSize(100, 22));
                button1.SetFrameOrigin(new CGPoint(10, 10));
                button1.Menu = menu;
                View.AddSubview(button1);
                button1.myHandler += (s,e) =>
                {
                    index = 1;
                };
    
    
    
                MyButton button2 = new MyButton();
                button2.Title = "Button2";
                button2.Tag = 2;
                button2.SetFrameSize(new CGSize(100, 22));
                button2.SetFrameOrigin(new CGPoint(10, 40));
                button2.Menu = menu;
                View.AddSubview(button2);
                button1.myHandler += (s, e) =>
                {
                    index = 2;
                };
            }
    
    
            private void menuClicked(object sender, EventArgs e)
            {
    
                if(index == 1)
                {
                    //button1
                }
                else if(index == 2)
                {
                    //button2
                }
    
                Console.WriteLine("Menu clicked - which button popped up the menu?");
            }
        }
    

    Xamarin forums are migrating to a new home on Microsoft Q&A!
    We invite you to post new questions in the Xamarin forums’ new home on Microsoft Q&A!
    For more information, please refer to this sticky post.

Answers

  • ColeXColeX Member, Xamarin Team Xamurai
    edited December 2020 Accepted Answer

    We right click on the button to show the pop up menu , so that we can detect it in right-click event of the Button .

    First ,we need to create new subclass NSButton, and then override RightMouseDown method .

    Detect when right click on the button

    public class MyButton : NSButton
        {
    
            public override void RightMouseDown(NSEvent theEvent)
            {
                nint tag = this.Tag;  //get which button 
            }
        }
    
    

    Detect when click on the menuItem

    public class MyButton : NSButton
        {
    
            public delegate void MyHandler(object sender,EventArgs e);
            public event MyHandler myHandler;
    
            public override void RightMouseDown(NSEvent theEvent)
            {
                myHandler(this,null);
            }
        }
    
        public partial class ViewController : NSViewController
        {
            public ViewController(IntPtr handle) : base(handle)
            {
            }
    
            int index = 0;
    
            public override void ViewDidLoad()
            {
                base.ViewDidLoad();
    
                // Do any additional setup after loading the view.
    
    
                NSMenu menu = new NSMenu();
                NSMenuItem menuItem = new NSMenuItem("Test");
                menuItem.Activated += menuClicked;
                menu.AddItem(menuItem);
    
                MyButton button1 = new MyButton();
                button1.Title = "Button1";
                button1.Tag = 1;
                button1.SetFrameSize(new CGSize(100, 22));
                button1.SetFrameOrigin(new CGPoint(10, 10));
                button1.Menu = menu;
                View.AddSubview(button1);
                button1.myHandler += (s,e) =>
                {
                    index = 1;
                };
    
    
    
                MyButton button2 = new MyButton();
                button2.Title = "Button2";
                button2.Tag = 2;
                button2.SetFrameSize(new CGSize(100, 22));
                button2.SetFrameOrigin(new CGPoint(10, 40));
                button2.Menu = menu;
                View.AddSubview(button2);
                button1.myHandler += (s, e) =>
                {
                    index = 2;
                };
            }
    
    
            private void menuClicked(object sender, EventArgs e)
            {
    
                if(index == 1)
                {
                    //button1
                }
                else if(index == 2)
                {
                    //button2
                }
    
                Console.WriteLine("Menu clicked - which button popped up the menu?");
            }
        }
    

    Xamarin forums are migrating to a new home on Microsoft Q&A!
    We invite you to post new questions in the Xamarin forums’ new home on Microsoft Q&A!
    For more information, please refer to this sticky post.

  • Dutch2Dutch2 Member ✭✭

    Thanks ColeX for your reply.

    Coming from Visual Studio for Windows I'm used to having all the events handed to me by default.

    Your code helped me make it work, this is that I came up with, please let me know if you see something unusual.

    `
    int activeButton = -1;

        public override void ViewDidLoad()
        {
            base.ViewDidLoad();
    
            NSMenu menu = new NSMenu();
            NSMenuItem menuItem = new NSMenuItem("Test");
            menuItem.Activated += menuClicked;
            menu.AddItem(menuItem);
    
            MyButton button1 = new MyButton();
            button1.Title = "Button1";
            button1.Tag = 1;
            button1.SetFrameSize(new CGSize(100, 22));
            button1.SetFrameOrigin(new CGPoint(10, 10));
            button1.Menu = menu;
            button1.myHandler += RightClickHandler;
            View.AddSubview(button1);
    
            MyButton button2 = new MyButton();
            button2.Title = "Button2";
            button2.Tag = 2;
            button2.SetFrameSize(new CGSize(100, 22));
            button2.SetFrameOrigin(new CGPoint(10, 40));
            button2.Menu = menu;
            button2.myHandler += RightClickHandler;
            View.AddSubview(button2);
        }
    
        private void RightClickHandler(object sender, EventArgs e)
        {
            NSButton button = sender as NSButton;
            activeButton = (int)button.Tag;
        }
    
        private void menuClicked(object sender, EventArgs e)
        {
            Console.WriteLine("Menu clicked from button " + activeButton);
        }`
    

    `
    public class MyButton : NSButton
    {

        public delegate void MyHandler(object sender, EventArgs e);
        public event MyHandler myHandler;
    
        public override void RightMouseDown(NSEvent theEvent)
        {
            myHandler(this, null);
            base.RightMouseDown(theEvent);
        }
    }`
    
Sign In or Register to comment.