Search code examples
c#winformssender

What is the most appropriate way to reference a sender element in C# forms?


I'm making a C# form application in which I have a couple of textboxes and comboboxes with placeholder text. I am trying to make it so that whenever said elements enter focus, they will call a method to erase the placeholder text and change its color.

In my little knowledge, it seemed appropriate to create a method that received the enter focus event's "sender" argument. Something along the lines of...

private void txtName_Enter(object sender, EventArgs e)
    {
        CoolMethod(sender);
        
    }

public void CoolMethod(object sender)
    {
        sender.Text = "";
    }

But that doesn't work. I expected having access to the element's properties much as if I were to simply type txtName.(something). Why does it not? How can I do this instead?

I tried looking up documentation on elements and events but it fried my brain. I'm not even sure what I'm looking for here to understand what I need and I figured someone else explaining in more human words could help. Sorry if it's a silly question, but I really didn't manage to figure it out on my own.


Solution

  • Why does it not?

    Because Object does not have a .Text property.

    ...but simply cast your "sender" parameter to type Control, which does have a .Text property. Don't forget to change the type of the parameter in CoolMethod() as well:

    private void txtName_Enter(object sender, EventArgs e)
    {
        CoolMethod((Control)sender)        
    }
    
    public void CoolMethod(Control sender)
    {
        sender.Text = "";
    }
    

    From the comments:

    Thank you! Worked wonders. I would like to ask about the (Control)sender bit. I've never seen passing an argument with a different, specified type. What do you suggest I look up to learn about that? Why can the same sender have different types?

    Here's the docs on Casting.

    All classes in .Net derive from Object, which means you can reference all controls with a variable declared of type Object. This isn't always a two way street, though.

    All squares are rectangles, but not all rectangles are squares.

    So all TextBoxes, for instance, can be referenced with an Object variable, but not all Objects can be cast to TextBox (it might be something else).

    In this case, we can be fairly certain that the "sender" parameter is going to be a Control, since that event is generated by a Control. It is possible to call txtName_Enter() manually, though, and pass in parameters that DO NOT make sense.

    To guard against that, you can check to see if the sender parameter is of type Control before casting. That would like:

    private void txtName_Enter(object sender, EventArgs e)
    {
        if (sender is Control) // if we pass this test, it's safe to cast to Control below!
        {
            CoolMethod((Control)sender)
        }       
    }