需要一种更好的方法来循环访问表单控件

本文关键字:循环 方法 访问 访问表 控件 表单 更好 一种 | 更新日期: 2023-09-27 18:35:51

在我用 C# 编写的 WinForms 应用程序中,一个窗体上有一个按钮,它需要稍微改变另一个窗体的外观(只需更改按钮上的文本)。

我已经设法做到了这一点,但是代码太长了,我相信必须有一种更简洁的方式来实现同样的事情。

这是我在表单上的按钮 frm冲突的代码,以及它如何更改表单 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);
        }

任何有助于显著减少代码量的帮助将不胜感激,因为我将需要在我的应用程序中其他位置的表单之间进行类似的交互。

需要一种更好的方法来循环访问表单控件

如果您的按钮是通过设计器添加的,并且不是动态创建的,则解决方案很简单:在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");
}

我认为这对你有帮助

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";
        }
}

如果第二个的外观需要从你那里改变第一个,你应该用另一种方式解决这个问题。

最好的是,需要更改的按钮应打开以捕获窗体二打开的事件,然后应用所需的更改。

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

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

您可以使用

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"; 

你可以创建一个公共属性并从你的窗体订阅一个 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 属性的值,它也是双向绑定。