C# 将事件TextChanged分配给表单中的所有文本框

C# 将事件TextChanged分配给表单中的所有文本框,c#,.net,winforms,textbox,C#,.net,Winforms,Textbox,您好,我想知道我怎样才能保持对所有文本框的关注,无论它们中的任何一个是否改变了值。我看到一些代码 一个写这段代码的人说“它不能被分配到面板和文本框中的文本框” 所以我的问题是,由于我几乎拥有groubox或panel中的所有文本框,我如何才能看到panels或groupbox中的文本框是否发生了更改?当您必须处理嵌套控件时,1 for loop就帮不上忙了。您必须使用某种递归方法或自定义堆栈来循环所有控件,如下所示: private void RegisterTextChangedEventHa

您好,我想知道我怎样才能保持对所有
文本框
的关注,无论它们中的任何一个是否改变了值。我看到一些代码

一个写这段代码的人说“它不能被分配到面板和文本框中的文本框”


所以我的问题是,由于我几乎拥有groubox或panel中的所有文本框,我如何才能看到panels或groupbox中的文本框是否发生了更改?

当您必须处理嵌套控件时,1 for loop就帮不上忙了。您必须使用某种递归方法或自定义
堆栈
来循环所有控件,如下所示:

private void RegisterTextChangedEventHandler(Control root){
   Stack<Control> stack = new Stack<Control>();
   stack.Push(root);  
   Control current = null;     
   while(stack.Count>0){
      current = stack.Pop();
      foreach(var c in current.Controls){
         if(c is TextBox) ((TextBox)c).TextChanged += textChanged;
         stack.Push(c);
      }
   }
}
private void textChanged(object sender, EventArgs e){
   //....
}
//Use it
RegisterTextChangedEventHandler(yourForm);//Or your container ....
private void RegisterTextChangedEventHandler(控制根){
堆栈=新堆栈();
栈.推(根);
控制电流=零;
而(堆栈计数>0){
当前=stack.Pop();
foreach(当前控件中的var c){
如果(c是文本框)((文本框)c).TextChanged+=TextChanged;
堆栈推送(c);
}
}
}
私有void textChanged(对象发送方,事件参数e){
//....
}
//使用它
RegisterTextChangedEventHandler(您的表单)//或者你的容器。。。。

当您必须处理嵌套控件时,1 for循环就无能为力了。您必须使用某种递归方法或自定义
堆栈
来循环所有控件,如下所示:

private void RegisterTextChangedEventHandler(Control root){
   Stack<Control> stack = new Stack<Control>();
   stack.Push(root);  
   Control current = null;     
   while(stack.Count>0){
      current = stack.Pop();
      foreach(var c in current.Controls){
         if(c is TextBox) ((TextBox)c).TextChanged += textChanged;
         stack.Push(c);
      }
   }
}
private void textChanged(object sender, EventArgs e){
   //....
}
//Use it
RegisterTextChangedEventHandler(yourForm);//Or your container ....
private void RegisterTextChangedEventHandler(控制根){
堆栈=新堆栈();
栈.推(根);
控制电流=零;
而(堆栈计数>0){
当前=stack.Pop();
foreach(当前控件中的var c){
如果(c是文本框)((文本框)c).TextChanged+=TextChanged;
堆栈推送(c);
}
}
}
私有void textChanged(对象发送方,事件参数e){
//....
}
//使用它
RegisterTextChangedEventHandler(您的表单)//或者你的容器。。。。

您需要另一个循环用于
分组框
面板
,您可以使用以下代码:

private void addEvents(Control.ControlCollection ct)
{
    foreach (Control ctrl in ct)
    {
        if (ctrl is TextBox)
        {
            TextBox tb = (TextBox)ctrl;
            tb.TextChanged += new EventHandler(tb_TextChanged);
        }
        else if (ctrl is GroupBox || ctrl is Panel) addEvents(ctrl.Controls);
    }
}

private void Form1_Load(object sender, EventArgs e)
{
    addEvents(this.Controls);
}

void tb_TextChanged(object sender, EventArgs e)
{
    TextBox tb = (TextBox)sender;
    tb.Tag = "CHANGED"; // or whatever
}

您需要另一个循环用于
分组框
面板
,您可以使用以下代码:

private void addEvents(Control.ControlCollection ct)
{
    foreach (Control ctrl in ct)
    {
        if (ctrl is TextBox)
        {
            TextBox tb = (TextBox)ctrl;
            tb.TextChanged += new EventHandler(tb_TextChanged);
        }
        else if (ctrl is GroupBox || ctrl is Panel) addEvents(ctrl.Controls);
    }
}

private void Form1_Load(object sender, EventArgs e)
{
    addEvents(this.Controls);
}

void tb_TextChanged(object sender, EventArgs e)
{
    TextBox tb = (TextBox)sender;
    tb.Tag = "CHANGED"; // or whatever
}

您可以使您的方法递归:

private void Form1_Load(object sender, EventArgs e)
{
    Assign(this);
}

void Assign(Control control)
{
    foreach (Control ctrl in control.Controls)
    {
        if (ctrl is TextBox)
        {
            TextBox tb = (TextBox)ctrl;
            tb.TextChanged += new EventHandler(tb_TextChanged);
        }
        else
        {
            Assign(ctrl);
        }
    }
}

void tb_TextChanged(object sender, EventArgs e)
{
    TextBox tb = (TextBox)sender;
    tb.Tag = "CHANGED"; // or whatever
}

只需为该方法找到一个更好的名称,而不是
Assign

您可以使您的方法递归:

private void Form1_Load(object sender, EventArgs e)
{
    Assign(this);
}

void Assign(Control control)
{
    foreach (Control ctrl in control.Controls)
    {
        if (ctrl is TextBox)
        {
            TextBox tb = (TextBox)ctrl;
            tb.TextChanged += new EventHandler(tb_TextChanged);
        }
        else
        {
            Assign(ctrl);
        }
    }
}

void tb_TextChanged(object sender, EventArgs e)
{
    TextBox tb = (TextBox)sender;
    tb.Tag = "CHANGED"; // or whatever
}

请为该方法找到一个更好的名称,而不是
Assign

您尝试过吗?我认为它不起作用的唯一原因是您没有迭代
this.Controls
的子项。例如,表单->面板->文本框,因此您需要使循环递归并检查子对象的所有子对象等,以检查表单上的所有文本框。您尝试过吗?我认为它不起作用的唯一原因是您没有迭代
this.Controls
的子对象。例如,表单->面板->文本框,因此您需要使循环递归并检查子对象的所有子对象等,以检查表单上的所有文本框。您认为这可能需要稍微调整一下,因为如果子对象是文本框,您只会将子对象推送到堆栈上,而如果它不是文本框,您只想推?除此之外,非常干净的代码/实现@谢谢,有点小错误。事实上,我还想允许将
TextBox
推入堆栈,否则使用
else
就可以了,只是更新了代码。我想这可能需要稍微调整一下,因为如果子对象是文本框,您只会将子对象推到堆栈上,而如果它不是文本框,您只想推?除此之外,非常干净的代码/实现@谢谢,有点小错误。事实上,我还想允许将
TextBox
推入堆栈,否则使用
else
就可以了,只需更新代码即可。