在 C# 表单中引用发件人元素的最合适方法是什么?

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

我正在制作一个 C# 表单应用程序,其中有几个带有占位符文本的文本框和组合框。我试图做到这一点,以便每当所述元素进入焦点时,它们都会调用一种方法来擦除占位符文本并更改其颜色。

据我所知,创建一个接收进入焦点事件的“发送者”参数的方法似乎是合适的。类似于...

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

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

但这不起作用。我希望能够像简单地键入 txtName.(something) 一样访问元素的属性。为什么不呢?我该怎么做呢?

我试着查找有关元素和事件的文档,但它让我大吃一惊。我什至不确定 什么 我在这里寻找了解我需要的东西,我认为其他人用更人性化的语言解释会有所帮助。 对不起,如果这是一个愚蠢的问题,但我真的没有设法自己弄清楚。

Why does it not?

因为Object没有.Text 属性.

...但只需将您的“发件人”参数转换为类型 Control,它确实有一个 .Text 属性。不要忘记更改 CoolMethod() 中的参数类型:

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

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

来自评论:

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?

这是 Casting 上的文档。

.Net 中的

All 类 派生自Object,这意味着您可以使用声明为Object 类型的变量来引用所有控件。不过,这并不总是一条双向街道。

所有正方形都是长方形,但并非所有长方形都是正方形。

因此,例如,所有 TextBox 都可以用对象变量引用,但并非所有对象都可以转换为 TextBox(可能是其他类型)。

在这种情况下,我们可以相当确定“sender”参数将是一个控件,因为该事件是由控件生成的。但是,可以手动调用 txtName_Enter(),并传入没有意义的参数。

为了防止这种情况,您可以在转换前检查类型 Control 的发送者参数 is 是否。那会是:

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)
    }       
}