如何在所谓的事件中找到引发事件的控件? Visual C#

时间:2009-12-08 12:46:19

标签: c# winforms

我正在编写一个C#程序,它接受一堆参数并对数据点进行一些转换,然后将它们绘制到屏幕上。

在我的一个表单上,我有一堆TextBoxes,我都希望执行相同的KeyPress事件。之前我会做一个switch语句,它只会接收KeyPress事件的发送者并将其与所有TextBox进行比较。这种方法对我来说似乎不太高效,因为现在我有20多个TextBox。

我想要做的是找到表单上的哪个TextBox发送了KeyPress事件,并从该TextBox获取更多信息(IE的Text值等)。这样可以省去我不得不与发送者进行大量切换以查看TextBox相同的问题。但我刚刚度过了最艰难的时光。

我查看了System.Windows.Controls& System.Windows.Forms类,看看我是否能找到任何可以帮助我的东西。我正在寻找的东西可以让我看到哪个控件有焦点。也许这就是我应该寻找的东西?我还看了一下我在KeyPress事件中可以对发件人做些什么来看看我是否能弄清楚TextBox引发了什么事情并且仍然没有运气。

此时我觉得自己更加困惑。任何帮助将不胜感激。

4 个答案:

答案 0 :(得分:10)

发件人方法应该没问题。但是,您可以演员:

TextBox txt = (TextBox) sender; // or "as" if you aren't sure.
                                // you can also just cast to Control for most
                                // common properties
// perhaps look at txt.Name, txt.Text, or txt.Tag

请注意,有些情况下发件人不是您的想法,但这是罕见的,主要涉及通过以下代码转发事件:

public event EventHandler AcceptClick {
    add { acceptButton.Click += value;}
    remove { acceptButton.Click -= value;}
}

此处,sender将是acceptButton,您无法看到。但通常这不是问题。

答案 1 :(得分:7)

有一个约定,传递给事件处理程序的第一个参数是发送事件的控件,所以你可以像这样抛出它:

void myTextBox_EventHandler(object sender, EventArgs args)
{
    TextBox textBox = (TextBox)sender;
    ...
}

答案 2 :(得分:1)

您可以使用控件的标记属性来区分多个文本框。 为此,首先,您需要为每个文本框分配标记属性,并且在事件方法中,您可以访问标记属性。假设您要分配多个参数,然后创建一个单独的类,其中参数作为属性,并将类的对象分配给textbox的tag属性。

希望,它有所帮助

答案 3 :(得分:1)

我认为Marc和GraemeF的答案很棒,但我会添加一个答案(无论如何)作为一种略微替代方法的例子。这种方法反映了我的“松弛之路”:)编程哲学。请注意,此示例需要Linq。

我的第一个目标是让一个TextBox类型的变量可用于保存当前活动的TextBox(或者如果需要从外部访问表单,我可以通过公共属性):如果我能得到它,那么我有一个简单的方法来访问当前活动的TextBox的当前文本:只需使用.Text属性(不需要转换)。

    //on the Form where the TextBoxes are : make into a Public Property
    // if you need to access this from outside the Form holding the TextBoxes
    // a Form-level variable
    private TextBox theActiveTB;

然后,在Form上,我会让Form Load事件为我构建一个TextBoxes集合:并确保他们订阅了相同的'KeyPress和'Enter事件:

   // on the Form where the TextBoxes are : a Form-level variable
    private List<TextBox> tbList;

    // build the list of TextBoxes and set the same 'Enter event for each of them
    // note the assumption that every TextBox on the Form is going to be handled
    // in exactly the same way : probably better to isolate them in a Panel in case
    // you have other TextBoxes for other purposes ; then you'd just use the same
    // code here to enumerate all the TextBoxes in the Panel
    private void Form1_Load(object sender, EventArgs e)
    {
         tbList =
         (
            from TextBox theTB in this.Controls.OfType<TextBox>()
            select theTB
         ).ToList();

         foreach (TextBox theTB in tbList)
         {
            theTB.KeyPress +=new KeyPressEventHandler(theTB_KeyPress);
            theTB.Enter +=new EventHandler(theTB_Enter);
         }
    }

    // so here's what the Enter event might look like :
    private void theTB_Enter(object sender, EventArgs e)
    {
        theActiveTB = (TextBox)sender;

        // reality check ...
        // Console.WriteLine("entering : " + theActiveTB.Name);
    }

    // so here's what the KeyPress event might look like :
    private void theTB_KeyPress(object sender, KeyPressEventArgs e)
    {
        // do what you need to do here

        // access the Text in the Textbox via 'theActiveTB

        // reality check
        // Console.WriteLine(theActiveTB.Name + " : " + e.KeyChar );
    }

为什么要打扰List&lt; TextBox&gt;使用Linq?毕竟,你可以循环遍历Form(或Panel,或任何容器)并检查每个控件的类型,然后,如果它是TextBox,则在现场分配事件处理程序。我选择创建TextBoxes的通用列表的原因是:当我有一个具有特殊共享标识,目的或行为集的集合时,通常情况下我会想要对其内容执行其他操作作为“集合”或“集团”。