2013-03-05 41 views
0

我正在開發一個應用程序,我想包含一些全局功能,例如適用於應用程序包含的每個窗體的幾個按鈕。常規按鈕

這是一個MDI應用程序,其中包含四個子窗體,每個窗體執行不同的任務,並且每個窗體都有自己的控件。我在每個表單上都有一個Clear and Search按鈕,我想要做的是創建兩個全局按鈕,爲當前處於活動狀態的表單執行這些操作。

例如,Form1是MDI父級,Form2是Form1的子級。我從Form1中的ToolStripMenuItem調用Form2,我在Form2中有一個按鈕,清除其中的所有文本框。我想要實現的是將此按鈕中的代碼移動到位於Form1(MDI父級)中的常規欄中的按鈕,以便不僅清除Form2的文本框,還清除我在我的應用中的所有表單。

這是我到目前爲止有:

//Form1 code 
public partial class FrmPrincipal : Form 
{ 
    public FrmPrincipal() 
    { 
     InitializeComponent(); 
    } 
    private void manageUsersToolStripMenuItem_Click(object sender, EventArgs e) //Calling Form2 
    { 
     FrmUserManager frmusers = new FrmUserManager(); 
     frmusers.MdiParent = this; 
     frmusers.Show(); 

    } 
} 

//Form2 code 
public partial class FrmUserManager : Form 
{ 
    public FrmUserManager() 
    { 
     InitializeComponent(); 
    } 
} 

private void BtnClear_Click(object sender, EventArgs e) 
{ 
    Clear(this); 
} 

private void Clear(Control all) 
{ 
    foreach (Control all in all.Controls) 
    { 
     if (all is TextBox) ((TextBox)all).Text = string.Empty; 
     if (all is CheckBox) ((CheckBox)all).Checked = false; 
     if (all is DataGridView) ((DataGridView)all).DataSource = null; 
     if (all.Controls.Count > 0) Clear(all); 
    } 
} 

所以,基本上我想要的是這個代碼移動到Form1中的按鈕從窗體2之外執行此操作。如果我可以做到這一點,我將能夠擺脫四個子窗體中的按鈕(搜索和清除),此外,該應用程序將更易於使用。

我想到的唯一方法是改變財產「調節器」在Form2的每個控件「公共」,試圖從Form1上訪問它們做這樣的事情:

Form2 frm2 = new Form2(); 
if(frm2.Active == true) Clear(this); 

在這種情況下, ,我會實例化每個表單並驗證它是否處於活動狀態。

它沒有顯示任何錯誤,但仍然不起作用。我想我知道爲什麼,調用Form2創建的對象是與此處創建的對象完全不同的對象,因此當前顯示的Form2與此處引用的Form2不同。

有沒有人明白我想要做什麼?

+0

對不起,但我不得不說。 MDI是有史以來最糟糕的UI想法。 – 2013-03-05 17:38:19

+4

@HighCore您在WinForm類別中持續的拖曳評論不是很有幫助。隨意將WinForm標籤添加到Stack Overflow首頁的Ignore列表中。 – LarsTech 2013-03-05 17:50:19

+0

@LarsTech我沒有倒下任何東西。我通常不這樣做。你今天可以看看我的代表數據,看看沒有降薪。另外,我必須承認我的評論有時可能會令人討厭。我只是想把這些人叫醒。 – 2013-03-05 18:04:33

回答

0

您必須在創建子窗體時跟蹤您的子窗體。你可能想這樣做:

// In the MDI form  
List<Form> mChildForms = new List<Form>(); 

void ToolStripButton_Click(object sender, EventArgs args) 
{ 
    Form myForm = new FrmUserManager(); 
    ... 
    mChildForms.Add(myForm); 
} 

void BtnClear_Click(object sender, EventArgs args) 
{ 
    foreach (Form f in mChildForms) 
     if (f.Active) 
     Clear(f); 
} 

可能不準確,我現在沒有Visual Studio。

+0

您不需要創建列表來跟蹤子MDI表單,它由Form.MdiChildren屬性(http://msdn.microsoft.com/en-us /library/system.windows.forms.form.mdichildren.aspx) – virious 2013-03-05 18:39:58

+0

對,如果OP希望用戶能夠清除*每個*孩子,這是一個更好的方法。我會說Jcl的解決方案更好。但是這個假設對我來說並不清楚。 – Julien 2013-03-06 08:43:16

+0

感謝您花時間回答:) – Newbie 2013-03-06 16:01:42

0

爲什麼不把你的Clear功能Form2公開,然後就去做:

if(frm2.Active == true) frm2.Clear(frm2); 

或者,如果你想要這個任何的形式,結算活動之一,你只需移動Clear功能爲Form1,然後執行類似操作:

if(this.ActiveMDIChild != null) 
    Clear(this.ActiveMDIChild); 
+0

謝謝,非常感謝! – Newbie 2013-03-06 16:02:27

0

這些是我爲解決此問題所採取的步驟。

1.創建從Form繼承而來的具有公共ClearData()方法的類。

public class ClearableForm : Form 
{ 
    public void ClearData() 
    { 
     Action<Control> traverseControls = null; 

     traverseControls = (c) => 
     { 
      if (c is TextBox) ((TextBox)c).Text = string.Empty; 
      if (c is CheckBox) ((CheckBox)c).Checked = false; 
      if (c is DataGridView) ((DataGridView)c).DataSource = null; 
      c.Controls.Cast<Control>().ToList<Control>().ForEach(traverseControls); 
     }; 

     traverseControls(this); 
    } 
} 

2.請您FrmUserManager所以從ClearableForm繼承。

public partial class FrmUserManager : ClearableForm 
{ 
    public FrmUserManager() 
    { 
     InitializeComponent(); 
    } 
} 

3.添加 「清除」 ToolStripMenuItem到的MenuStrip您FrmPrincipal形式用下面的代碼上。

private void clearToolStripMenuItem_Click(object sender, EventArgs e) 
{ 
    foreach (Form mdi_child in this.MdiChildren) 
    { 
     if (mdi_child is ClearableForm) 
      mdi_child.ClearData(); 
    } 
} 

我希望它能解決您的問題。隊友的歡呼聲!

+1

我相信你在這裏增加了不必要的複雜性(過度工程)......但是,如果你要採取這種方法,那麼至少要點3檢查Mdi孩子是否是'ClearableForm'類型,否則這些都不是過度工程是有好處的(因爲你所有的Mdi孩子都必須是ClearableForm類型的)。 – Jcl 2013-03-06 06:44:59

+0

我不認爲它太複雜,因爲這個問題的解決方案。雖然我同意第3點,但會編輯它:)。 – virious 2013-03-06 06:48:16

+0

好得多。關於過度工程,由於'ClearData'可以應用於任何形式,我不認爲增加繼承水平是一條路。我親自將'ClearData'函數放在Mdi父類上(並將Form作爲參數添加到函數中)。並不是說你的方法是錯誤的,但爲此添加一定的繼承水平對我來說似乎有點太過分了(當然這是個人的看法)。 – Jcl 2013-03-06 06:52:39