需要一种更好的方法来迭代表单控件

时间:2013-10-18 09:59:09

标签: c# winforms

在我用C#编写的WinForms应用程序中,一个Form上有一个Button,需要稍微改变第二个Form的外观(只需更改Button上的Text)。

我已经设法做到了这一点,但代码非常长,我相信必须有一种更简洁的方法来实现同样的目标。

这是我的表单上的按钮frmConflicts的代码,以及它如何更改窗体frmAdmin上的按钮btnAddCase上的文本(工作,但似乎太长) -

private void btnNoConflicts_Click(object sender, EventArgs e)
    {
        try
        {
            foreach (Form f in Application.OpenForms)
            {
                if (f.Name == "frmAdmin")
                {
                    frmAdmin a = (frmAdmin)f;
                    a.conflictsClear = true;
                    foreach (Control ctrl in a.Controls)
                    {
                        if (ctrl.Name == "panAdmin")
                        {
                            foreach (Control ctrl2 in ctrl.Controls)
                            {
                                if (ctrl2.Name == "tabControlAdmin")
                                {
                                    TabControl tab = (TabControl)ctrl2;                                        
                                    foreach(TabPage page in tab.TabPages)
                                    {
                                        if (page.Name == "pageNewCase")
                                        {
                                            foreach (Control ctrl3 in page.Controls)
                                            {
                                                if (ctrl3.Name == "panCaseDetails")
                                                {
                                                    foreach (Control ctrl4 in ctrl3.Controls)
                                                    {
                                                        if (ctrl4.Name == "btnAddCase")
                                                        {
                                                            ctrl4.Text = "Add Case";                                                                
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            this.Close();
        }
        catch (Exception eX)
        {
            MessageBox.Show("frmConflicts: btnNoConflicts()" + Environment.NewLine + eX.Message);
        }

任何有助于显着减少代码量的帮助都会非常受欢迎,因为我需要在我的应用程序的其他地方进行类似的交互。

5 个答案:

答案 0 :(得分:5)

如果您的按钮是通过设计师添加的,并且未动态创建,则解决方案很简单:在frmAdmin内添加方法

public void ChangeCaption(string caption)
{
     btnAddCase.Text = "Add case";
}

然后

var frmAdmin = Application.OpenForms.OfType<Form>().FirstOrDefault(x => x.GetType() == typeof(frmAdmin));

if (frmAdmin != null)
{
    frmAdmin.ChangeCaption("Add case");
}

答案 1 :(得分:1)

我认为这对你很有帮助

foreach (Form f in Application.OpenForms)
{
     var controls =this.Controls.Find("btnAddCase", true);
     if(controls!=null)
        foreach(var control in controls)
        {
            control.Text="Add case";
        }
}

答案 2 :(得分:1)

如果第二个的出现需要先改变,你应该用另一种方式来解决这个问题。

最好的是,您需要更改的按钮应该打开以捕获表单2打开的事件,然后应用所需的更改。

在您声明按钮的位置,您应该为其分配一个侦听器,该侦听器将捕获Form2开头,然后应用操作。

所以在方法private void btnNoConflicts_Click(object sender, EventArgs e)中你应该触发该按钮的事件来捕获而不是搜索它。

答案 3 :(得分:0)

您可以使用LINQ + ControlCollection.Find

Control btnAddCase = Application.OpenForms.Cast<Form>()
    .Where(f => f.Name == "frmAdmin")
    .SelectMany(f => f.Controls.Find("btnAddCase", true)) // true means recursive
    .FirstOrDefault();
if(btnAddCase != null)
    btnAddCase.Text = "Add Case"; 

答案 4 :(得分:0)

您可以创建公共属性并从表单订阅PropertyChanged事件,您需要具有公共变量的类来扩展INotifyPropertyChanged。

//Your class
public class ButtonText : INotifyPropertyChanged
{
   private string _buttonText;

   public string ButtonValue
   {
      get{ return _buttonText; }
      set
      {
         //Sets the value of _buttonText to the value passed in an argument 
         _buttonText = value;
         RaisePropertyChanged("ButtonValue");
      }
   }
   protected void RaisePropertyChanged(string propertyName)
   {
      PropertyChangedEventHandler handler = PropertyChanged;
      if (handler != null)
      {
         handler(this, new PropertyChangedEventArgs(propertyName));
      }
   }

   public event PropertyChangedEventHandler PropertyChanged;
}

在您的表单类中,您将绑定到ButtonText类的属性ButtonValue属性,如下所示:

ButtonText buttonObj = new ButtonText();
//Property field to bind, object to bind, property to bind
btnAddCase.DataBindings.Add("Text", buttonObj,"ButtonValue");
buttonObj.ButtonText = "Your text to bind.";

因为btnAddCase.Text属性绑定到ButtonText类的ButtonValue属性,所以btnAddCase.Text属性将始终反映ButtonText.ButtonValue属性的值,它也是双向绑定。