Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/300.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用委托在UserControl上从活动窗体获取到另一窗体的值_C#_Winforms_Delegates - Fatal编程技术网

C# 如何使用委托在UserControl上从活动窗体获取到另一窗体的值

C# 如何使用委托在UserControl上从活动窗体获取到另一窗体的值,c#,winforms,delegates,C#,Winforms,Delegates,我的Winform应用程序有3种形式:MainForm、Form1和Form2。 MainForm有一个UserControl;当应用程序启动时,它调用MainForm,MainForm将被加载并将Form1添加到UserControl: private void MainForm_Load(object sender, EventArgs e) { Form1 frm = new Form1() { Dock = DockStyle.Fill, TopLevel = false, Vis

我的Winform应用程序有3种形式:MainForm、Form1和Form2。 MainForm有一个UserControl;当应用程序启动时,它调用MainForm,MainForm将被加载并将Form1添加到UserControl:

private void MainForm_Load(object sender, EventArgs e)
{
   Form1 frm = new Form1() { Dock = DockStyle.Fill, TopLevel = false, Visible = true };
   xtraUserControl1.Controls.Add(frm);
}
在表格1中,我使用委托:

    public delegate void Tranferdata(string txt);
    public Tranferdata _tranfer;
    private void Gettxt(string txt)
    {
        tbx_Recieve.Text = txt;
    }
Form1有一个调用Form2的按钮:

private void button1_Click(object sender, EventArgs e)
{
    Form2 frm2 = new Form2();
    frm2.ShowDialog(this);
}
Form2将在关闭后向Form1发送值,Form2上的代码:

private void Form2_FormClosed(object sender, FormClosedEventArgs e)
{
    using (Form1 frm1 = (Form1)this.Owner)
    {
       frm1._tranfer(tbx_Numb.Text);
    }
}

private void button1_Click_1(object sender, EventArgs e)
{
   this.Close();
}
但是我的代码不能正常工作。它在“使用(Form1 frm1=(Form1)this.Owner)”时崩溃,并显示System.InvalidCastException。
如何修复此问题?

它在该行崩溃的原因是您没有将Form1设置为Form2的所有者

要解决此问题,请首先将Form1作为类变量而不是局部变量:

Form1 form1;
private void MainForm_Load(object sender, EventArgs e)
{
   form1 = new Form1() { Dock = DockStyle.Fill, TopLevel = false, Visible = true };
   xtraUserControl1.Controls.Add(form1);
}
然后,您可以在创建Form2时使用它来指定其所有者:

private void button1_Click(object sender, EventArgs e)
{
    Form2 frm2 = new Form2();
    frm2.Owner = form1;
    frm2.ShowDialog(this);
}

和Ron Beyer评论中提到的一样,考虑删除使用语句,它将关闭Frim1,这听起来不是你想要做的。

现在,虽然这种方法会奏效,但在这里你应该考虑一些问题: 你当初为什么选择使用“所有者”财产?你真的需要它吗?将Form1作为Form2的所有者意味着当Form1关闭时,Form2将关闭。由于在Form2上使用ShowDialog,它将阻止用户在Form2显示时关闭Form1,因此似乎不需要它。 如果使用Owner属性的原因仅仅是为了使用委托,那么您可以在Form2中添加一个Form1类型的属性,这将为您提供类型安全性和高级代码


但是还有更好的方法:MainForm可以注册到Form2的Closed事件并调用Form1的方法。这将删除不必要的依赖项(Form2和Form1根本不了解彼此),使代码更健康

该行崩溃的原因是您没有将Form1设置为Form2的所有者

要解决此问题,请首先将Form1作为类变量而不是局部变量:

Form1 form1;
private void MainForm_Load(object sender, EventArgs e)
{
   form1 = new Form1() { Dock = DockStyle.Fill, TopLevel = false, Visible = true };
   xtraUserControl1.Controls.Add(form1);
}
然后,您可以在创建Form2时使用它来指定其所有者:

private void button1_Click(object sender, EventArgs e)
{
    Form2 frm2 = new Form2();
    frm2.Owner = form1;
    frm2.ShowDialog(this);
}

和Ron Beyer评论中提到的一样,考虑删除使用语句,它将关闭Frim1,这听起来不是你想要做的。

现在,虽然这种方法会奏效,但在这里你应该考虑一些问题: 你当初为什么选择使用“所有者”财产?你真的需要它吗?将Form1作为Form2的所有者意味着当Form1关闭时,Form2将关闭。由于在Form2上使用ShowDialog,它将阻止用户在Form2显示时关闭Form1,因此似乎不需要它。 如果使用Owner属性的原因仅仅是为了使用委托,那么您可以在Form2中添加一个Form1类型的属性,这将为您提供类型安全性和高级代码


但是还有更好的方法:MainForm可以注册到Form2的Closed事件并调用Form1的方法。这将删除不必要的依赖项(Form2和Form1根本不了解彼此),使代码更健康

我找到了这个问题的解决方案: 表格2:

public void SetParent(Form1 frm)
{
    frm1 = frm;
}
并在事件调用form2的表格1中调用:

private void button1_Click(object sender, EventArgs e)
{
    Form2 frm2 = new Form2();
    frm2.SetParent(this);
    frm2.ShowDialog();
}

我找到了这个问题的解决方案: 表格2:

public void SetParent(Form1 frm)
{
    frm1 = frm;
}
并在事件调用form2的表格1中调用:

private void button1_Click(object sender, EventArgs e)
{
    Form2 frm2 = new Form2();
    frm2.SetParent(this);
    frm2.ShowDialog();
}


当您这样强制转换时,不要使用语句将其放入
中,否则您将处理传递到closed方法中的
Form1
实例。只有在处理完对象后要销毁该对象时,才能使用
using
。还有其他原因导致它无法工作(
sender
是一个Form2,而不是Form1),但您正在使用大锤敲打学员的图片钉并传送…感谢您的关注,但我不希望这样。我最好使用Delegate@MelvinCan你告诉我怎么做@RonBeyer@RonBeyer您能告诉我如何更正此代码吗?的可能副本在您这样强制转换时,不要使用
语句将其放入
中,否则您将处理传递到closed方法中的
Form1
实例。只有在处理完对象后要销毁该对象时,才能使用
using
。还有其他原因导致它无法工作(
sender
是一个Form2,而不是Form1),但您正在使用大锤敲打学员的图片钉并传送…感谢您的关注,但我不希望这样。我最好使用Delegate@MelvinCan你告诉我怎么做@RonBeyer@RonBeyer你能告诉我如何更正这个代码吗?我根据你的建议重写了我的代码,但我在frm1再次崩溃;(类型为“System.NullReferenceException”的异常)。我认为问题在于Form2的程序定义父窗体是MainForm,而不是Form1,因为Form1是在MainForm上添加到UC的,frm1或tbx_Numb都没有分配。在该行上放置一个断点,调试应用程序直到到达断点,然后检查这两个值以查看哪个值未分配。然后相应地修复代码。如果您仍然需要帮助,请在此处发布新代码,我将尽力提供帮助。我不知道如何在注释中编写代码。我的代码做了一些修改:不使用“using(Form1-frm1=(Form1)this.Owner)”而是“Form1-frm1=(Form1)this.Owner”。请,我需要帮助你调试你的代码。放置一个断点(通过右键单击该行并选择添加断点),然后按F5对其进行调试。运行场景,直到到达断点。然后将鼠标悬停在frm1和tbx_Numb上,看哪一个为空。我多次跟踪此代码,我也知道frm1为空。但我不知道如何修复这种情况。我根据您的建议重写了代码,但我在frm1再次崩溃;(类型为“System.NullReferenceException”的异常)。我认为问题在于Form2的程序定义父窗体是MainForm,而不是Form1,因为