2013-03-05 42 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