简体   繁体   中英

C# - Passing custom arguments to events

So I was trying to send custom arguments to an event, but it never worked, I tried so many different methods, but I never got it to work, So basically!

public void CreateEmojiList()
        {
            CreateAllEmojis();
            int btnCount = 0;

            foreach(Emoji emoji in emojiList)
            {
                Button btnEmoji = new Button();
                btnEmoji.Size = new Size(40, 36);
                btnEmoji.FlatStyle = FlatStyle.Flat;
                btnEmoji.FlatAppearance.MouseDownBackColor = Color.Cyan;
                btnEmoji.Cursor = Cursors.Hand;
                btnEmoji.Font = new Font("Bahnschrift", 6.75f);
                btnEmoji.Text = emoji.EmojiText;
                btnEmoji.Top = (panel_main.Controls.OfType<Button>().Count<Button>() / 4) * (1 + btnEmoji.Height) + 6;
                btnEmoji.Left = (btnEmoji.Width + 1) * btnCount + 6;
                panel_main.Controls.Add(btnEmoji);
                btnEmoji.Click += //What do I do here?
;                btnCount++;

                if (btnCount == 4)
                    btnCount = 0;
            }
        }

        protected virtual void OnEmojiClick(EmojiClickEventArgs e)
        {
            if (this.EmojiClick != null)
                EmojiClick(e);
        }

this is the class I want to use to pass my arguments:

public class EmojiClickEventArgs : EventArgs
    {
        private string emojiText;
        private string emojiName;

        public EmojiClickEventArgs(string EmojiText, string EmojiName)
        {
            this.EmojiText = EmojiText;
            this.EmojiName = EmojiName;
        }

        public string EmojiText { get { return emojiText; } set { emojiText = value; } }
        public string EmojiName { get { return emojiName; } set { emojiName = value; } }
    }

I want to get those two values from emoji.EmojiText and emoji.EmojiName

One way is to inherit from Button and create a class called EmojiButton . You then declare a delegate that matches the signature of the your event handler. After that, declare an event using the delegate in the EmojiButton class, add property like EmojiText and EmojiName to the button subclass as well. Finally you need to link the button click event with your custom event. Whenever the button is clicked, raise your event and pass your arguments ie this.EmojiText, this.EmojiName .

Another way is to assign your Emoji objects to the Tag property. You can then write the event handler with the normal EventHandler signature ( object sender, EventArgs e ), and look at what the sender 's Tag is. You then cast the Tag to an Emoji and access its properties.

You can take advantage of closures to "package up" the additional event data for each button's event handler. Just make sure not to close over the loop variable.

    public void CreateEmojiList()
    {
        CreateAllEmojis();
        int btnCount = 0;

        foreach(Emoji emoji in emojiList)
        {
            Button btnEmoji = new Button();
            btnEmoji.Size = new Size(40, 36);
            btnEmoji.FlatStyle = FlatStyle.Flat;
            btnEmoji.FlatAppearance.MouseDownBackColor = Color.Cyan;
            btnEmoji.Cursor = Cursors.Hand;
            btnEmoji.Font = new Font("Bahnschrift", 6.75f);
            btnEmoji.Text = emoji.EmojiText;
            btnEmoji.Top = (panel_main.Controls.OfType<Button>().Count<Button>() / 4) * (1 + btnEmoji.Height) + 6;
            btnEmoji.Left = (btnEmoji.Width + 1) * btnCount + 6;
            panel_main.Controls.Add(btnEmoji);
            var emojiCopy = emoji; //don't close on the loop variable!
            btnEmoji.Click += (sender,args) => OnEmojiClick(emojiCopy);
            btnCount++;

            if (btnCount == 4)
                btnCount = 0;
        }
    }

    protected virtual void OnEmojiClick(Emoji emoji)
    {
        //do something
    }

The fastest solution that comes to my mind and that doesn't imply the definition of custom UserControl classes, the subclassing of Button and other similar practices is:

btnEmoji.Click += (sender, e) =>
{
    Button b = (Button)sender;

    // let's suppose that the button name corresponds to the emoji name
    String emojiName = b.Name; 
    // let's suppose that the button tag contains the emoji text
    String emojiText = (String)b.Tag;

    Emoji_Clicked(sender, e, (new EmojiClickEventArgs(emojiText, emojiName)));
};

private void Emoji_Clicked(Object sender, EventArgs e, EmojiClickEventArgs ee)
{
    // Your code...
}

First and foremost thing you need to define delegate ,then create an instance.

class Emojis
{
       // public delegate void EmojiClickEventHandler(object sender,EventArgs args);
       //public event EmojiEventHandler EmojiClicked;
       //you can use above two lines or replace them instead below code.
        public event EventHandler<EmojiClickEventArgs> EmojiClicked;
        public void CreateEmojiList()
         {
             CreateAllEmojis();
             int btnCount = 0;
             //rest of the code
            panel_main.Controls.Add(btnEmoji);
            btnEmoji.Click += OnEmojiClick(btnEmoji);
            btnCount++;
        }

   protected virtual void OnEmojiClick(Button emoji)
   {
    //Here null check to handle if no subscribers for the event
    if(EmojiClicked!=null)
       {
           //there is no name property define for emoji but only text hence passing only text.
          EmojiClicked(this ,new  EmojiClickEventArgs(emoji.Text,emoji.Text){ });
       }
   }
   private void Emoji_Clicked(Object sender, EmojiClickEventArgs args)
        {
            Button mybutton = sender as Button;
            Console.WriteLine("emoji text "+ args.Text);
        }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM