这就是问题,我有调用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;
那么我怎样才能真正获得活动表格,这是另一种解决方案吗?或者我弄错了? 在此先感谢您的回答:)
答案 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();
}
}
}
快速而肮脏的解决方案的一个很好的例子,其中有一些固有的限制,通常只有在为时已晚时才识别它们 - 这就是我首先要说的原因;)