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

本文关键字:窗体 获取 UserControl 另一个 活动 何使用 | 更新日期: 2023-09-27 18:00:27

我的Winform应用程序有三个表单: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);
}

在Form1上,我使用委托:

    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。我该怎么解决这个问题?

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

它在那一行崩溃的原因是因为您没有将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在评论中提到的那样,考虑删除using语句,它会关闭Form1,听起来这不是你想做的。

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

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

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

public void SetParent(Form1 frm)
{
    frm1 = frm;
}

并在事件调用form2:中以form1调用它

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