如何使用委托将值从活动表单获取到 UserControl 上的另一个表单
How to get the value from active form to another form on UserControl using delegate
我的 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);
}
在 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();
}
但是我的代码不能正常工作。它在 'using (Form1 frm1 = (Form1)this.Owner)' 崩溃并显示 System.InvalidCastException。
我该如何解决这个问题?
它在该行崩溃的原因是您没有将 Form1 设置为 Form2 的所有者。
要修复,首先将 Form1 作为 class 变量而不是局部变量:
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,这听起来不像你想要的那样。
现在,虽然该方法可行,但您应该在此处考虑一些问题:
您为什么首先选择使用 "Owner" 属性?你真的需要它吗?将 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 时在 Form 1 中调用它:
private void button1_Click(object sender, EventArgs e)
{
Form2 frm2 = new Form2();
frm2.SetParent(this);
frm2.ShowDialog();
}
我的 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);
}
在 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();
}
但是我的代码不能正常工作。它在 'using (Form1 frm1 = (Form1)this.Owner)' 崩溃并显示 System.InvalidCastException。 我该如何解决这个问题?
它在该行崩溃的原因是您没有将 Form1 设置为 Form2 的所有者。
要修复,首先将 Form1 作为 class 变量而不是局部变量:
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,这听起来不像你想要的那样。
现在,虽然该方法可行,但您应该在此处考虑一些问题: 您为什么首先选择使用 "Owner" 属性?你真的需要它吗?将 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 时在 Form 1 中调用它:
private void button1_Click(object sender, EventArgs e)
{
Form2 frm2 = new Form2();
frm2.SetParent(this);
frm2.ShowDialog();
}