2013-10-18 33 views
2

在我用C#編寫的WinForms應用程序中,在一個表單上有一個按鈕,需要稍微改變第二個表單的外觀(只需更改按鈕上的文本)。需要一種更好的方式來遍歷表單控件

我已經做到了這一點,但代碼非常長,我相信必須有一個更簡潔的方法來實現同樣的事情。

這裏是我的表格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

如果您的按鈕是通過設計師的加入,而不是動態創建的解決方案很簡單:添加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"); 
} 
+0

這個答案的簡單性與我所擁有的相比是不可否認的 - 非常感謝你。 – PJW

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

這是一個啓發式代碼示例。它可能有效,但可能會產生意想不到的結果 –

+0

@Vash:OP只要求代碼相同,但更簡潔(_「顯着減少代碼量將不勝感激」_)。這裏是。它也是安全的,如果你改變一個名字,它不會拋出異常。 –

+0

這是真的在Gzaxx答案見。它符合OP的要求,並且可以在任何情況下工作。你的方法中的問題是,如果有兩個'btnAddCase'放置在'frmAdmin'層次結構的某處,那麼你的代碼可能會失敗。 –

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

如果第二個從第一個你需要改變的外觀應該以另一種方式解決這個問題。

最好的是,您需要更改的按鈕應該打開以捕獲表單二的事件,然後應用所需的更改。

在聲明按鈕的地方,您應該爲其分配一個偵聽器,該偵聽器將捕獲Form2打開,然後應用操作。

所以在方法private void btnNoConflicts_Click(object sender, EventArgs e)你應該觸發該按鈕的事件捕獲,而不是搜索它。

+0

最後,我很震驚沒有人更早指出這一點......不典型的SOF – Bolu

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屬性的值,這也是一種雙向綁定。

相關問題