如何从子表单引用表单?

时间:2011-10-19 03:16:00

标签: c# winforms

这就是问题,我有调用OrderForm.Show()的MainForm。 现在我想用一个按钮调用MainForm中的公共函数,但我不能。

以下是MainForm中的代码:

public partial class frmMain : Form
{
    public frmMain()
    {
        InitializeComponent();
    }

    // Main form
    private void MainFrm_Load(object sender, EventArgs e)
    {
        FormOrder frmO = new FormOrder();

        frmO.Show();
    }

    public void Refresh() 
    {
        // some action
    }
 }

在OrderForm中,我这样做:

public partial class FormOrder : Form
{
    public FormOrder()
    {
        InitializeComponent();
    }

    private void ShowForm()
    {
        // some action
    }

    private void btnCopy_Click(object sender, EventArgs e)
    {
        Form  form = Form.ActiveForm as frmMain;

        if (form != null)
        {
            form.Refresh();
        }

    }
}

所以在程序中我运行MainForm.Show()然后加载OrderForm。然后,当我单击“复制”按钮时,它将在MainForm中运行“公共功能刷新”。但我无法使它工作,它始终返回null:

  Form  form = Form.ActiveForm as frmMain;

那么我怎样才能真正获得活动表格,这是另一种解决方案吗?或者我弄错了? 在此先感谢您的回答:)

4 个答案:

答案 0 :(得分:4)

您获得的是null,因为您的活动表单是您所在的表单而不是frmMain类型。 (我认为你实际上可能会混淆父表单的活动表单?)

有这样的方法可以做到这一点。你可以让你的frmMain成为一个单身,但这很奇怪,很丑陋,不推荐迟到,或者你可以以某种方式将它的引用传递给它的孩子。这是一个简单的方法:

public partial class frmMain : Form
{
    public frmMain()
    {
        InitializeComponent();
    }

    // Main form
    private void MainFrm_Load(object sender, EventArgs e)
    {
        FormOrder frmO = new FormOrder(this); // pass a ref of self

        frmO.Show();
    }

    public void Refresh() 
    {
        // some action
    }
 }

在OrderForm中:

public partial class FormOrder : Form
{
    private frmMain _parent; // create a field that refers to the parent
    public FormOrder(frmMain parent) // mod the constructor
    {
        if (parent == null) throw new NullReferenceException("Can't be NULL!!!"); // check clause

        _parent = parent; // assign the ref of the parent

        InitializeComponent();
    }

    private void ShowForm()
    {
        // some action
    }

    private void btnCopy_Click(object sender, EventArgs e)
    {
            _parent.Refresh(); // make the call to parent
    }
}

你可以通过使用界面来改善这一点,但总体思路是一样的。

答案 1 :(得分:1)

我不建议您通过路线访问活动表单来完成目标。你需要做的是将MainForm的引用传递给OrderForm,因此OrderForm可以使用引用来调用MainForm上的任何方法。

private void MainFrm_Load(object sender, EventArgs e)
{
     FormOrder frmO = new FormOrder();
     frmO.MainForm = this;

     frmO.Show();
}

在FormOrder类中,您应该添加一个新属性MainForm,并使用该属性来引用调用表单: -

public partial class FormOrder : Form
{
    public Form MainForm;

    public FormOrder()
    {
        InitializeComponent();
    }

    private void ShowForm()
    {
        // some action
    }

    private void btnCopy_Click(object sender, EventArgs e)
    {
        if (MainForm != null)
        {
            MainForm.Refresh();
        }

    }
}

答案 2 :(得分:1)

您需要引用mainForm和/或mainForm的按钮单击事件,该事件位于mainForm之外。你可以通过各种方式做到这一点。创建一个静态类,该类具有对mainForm的引用,创建一个静态类,该委托具有对mainForm单击事件的委托,将mainForm传递给childForm的构造函数,将委托传递给mainForms单击事件到childForm的构造函数。创建一个处理click事件的静态方法,然后在childForm中使用它。

这完全取决于你想做什么,你需要做什么,以及你希望如何做。

答案 3 :(得分:1)

虽然其他答案绝对正确,但我想建议一种更容易但又“脏”的​​方法。

每个组件都有一个Tag属性,您可以在其中存储任何用户定义的值或引用。我们的想法是在第二种形式的Tag中保存对主窗体的引用,并从按钮单击事件处理程序访问它。

好处是您不必编写大量代码或创建任何数据结构。

关于它的脏东西是运行时的框架和编译时的编译器都不知道你在.Tag中存储了什么,并且因为它没有正确输入,您正在进行类型转换,具体取决于您事先存储正确的值。 如果在那里存储了错误的值,则可能很难调试原因,因为症状不会表明您将错误的值放入Tag的位置。如果你想要产生许多意想不到的难以检测和修复的错误,那么在程序员团队中如此疯狂Tag使用是一件好事:)

此外,每个组件只有一个Tag。如果您需要多个用户定义的值,您可能最终会创建一个自定义数据结构Tag然后保留一个引用,但这可能比所有其他建议更糟糕。

public partial class frmMain : Form
{
    public frmMain()
    {
        InitializeComponent();
    }

    // Main form
    private void MainFrm_Load(object sender, EventArgs e)
    {
        FormOrder frmO = new FormOrder();

        frmO.Tag=this;
        frmO.Show();
    }

    public void Refresh() 
    {
        // some action
    }
 }


public partial class FormOrder : Form
{
    public FormOrder()
    {
        InitializeComponent();
    }

    private void ShowForm()
    {
        // some action
    }

    private void btnCopy_Click(object sender, EventArgs e)
    {
        Form  form = Tag as frmMain; // form now references the main form

        if (form != null)
        {
            form.Refresh();
        }

    }
}

快速而肮脏的解决方案的一个很好的例子,其中有一些固有的限制,通常只有在为时已晚时才识别它们 - 这就是我首先要说的原因;)