使用C#中主窗体的子窗体中对象的信息

本文关键字:窗体 对象 信息 使用 | 更新日期: 2023-09-27 18:29:46

我有一个名为Form1.cs的C#表单。按下一个按钮,一个新的名为Form2.cs的表单出现,我用Form2做了一些事情。我有两种形式的变量。

我想像这样在这两种形式之间交流。

形式1:

string s=frm2.textbox1.text;`

形式2:

if(frm1.checkbox1.checked==true)

或者类似这些代码的东西。我已经尝试了以下代码:

形式1:

Form2 f=new Form2(this);
f.showDialog();`

形式2:

private Form1 mainForm = null;
public Form2(Form callingForm)
{
    mainForm = callingForm as Form1;
    InitializeComponent();
}
`

这是有效的。但我不想使用像"this"这样的指针来调用this.manifer。有没有其他方法可以在函数调用等形式之间进行通信?非常感谢。

使用C#中主窗体的子窗体中对象的信息

以下是几种不同的方法,可以消除Form 2了解Form 1的需要,并使Form 2可重用:

学员

您可以在第二个表单上声明一个委托函数,然后将委托方法从第一个表单传递给第二个,这样第二个窗体就可以回调第一个。

这种方法意味着你的第二张表格不再直接了解你的第一张表格。这也意味着你可以重用任何表格中的第二份表格,只需交给一位有正确签名的代表。以下示例:

表格1:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }
    private void button1_Click(object sender, EventArgs e)
    {
        Form2 f=new Form2(UpdateTextBox);
        f.ShowDialog();
    }
    private void UpdateTextBox(string newText)
    {
        label1.Text = newText;
    }
}

表格2:

public partial class Form2 : Form
{
    public delegate void ChoiceMadeOnForm2Delegate(string choice);
    private ChoiceMadeOnForm2Delegate _choiceDelegate;
    public Form2(ChoiceMadeOnForm2Delegate choiceDelegate)
    {
        InitializeComponent();
        _choiceDelegate = choiceDelegate;
    }
    private void saveButton_Click(object sender, EventArgs e)
    {
        _choiceDelegate(textBox1.Text);
        Close();
    }
}

在本例中,委托方法只有一个参数,但如果要将一系列值传递回Form 1,则委托方法声明可以包括更多参数,或者该参数可以是一个类。

如果您还想从Form 1中为Form 2设置初始值,那么您当然可以将这些值添加为Form 2的构造函数参数,并在新建Form 2时将其传入。

在您的示例中,Form 2显示为一个对话框,但如果您不想以模式显示Form 2,您甚至可以将Form 1上的委托传递给Form 2,这样表单就可以在两个方向上进行通信。

使用数据绑定和共享类

另一种方法是使用数据绑定,即将两个表单绑定到同一个对象,并在打开Form 2时在其构造函数中将该对象从Form 1传递给Form 2。当其中一种形式更改对象时,这些更改将同时立即反映在两种形式上。

要做到这一点,您需要了解一个名为databinding的概念,并在数据类上实现INotifyPropertyChanged接口。然后将两个窗体上的相关控件绑定到该类。关于INotifyPropertyChanged的文档可以在这里找到

只能传递Form2需要的信息,只能公开Form1需要的信息

Form1

string valueOfForm2 = null;
using Form2 f = new Form2(this.checkbox1.Checked)
{
    f.ShowDialog();
    valueOfForm2 = f.ReturnValue;
}

然后在Form1 中根据需要使用valueOfForm2

Form2

bool _IsForm1ValueChecked;
//By this property text will be exposed to outside of Form
public string ReturnValue { get { return this.textbox1.Text;} }
public Form2(bool isForm1ValueChecked)
{
    _IsForm1ValueChecked = isForm1ValueChecked;
}

_IsForm1ValueChecked将在构造器中设置,然后在Form2 中为您的目的使用它

我认为对于这样的东西,我使用的是属性。我不喜欢从一个窗体访问另一个窗体的控件。如果我需要一个表单的信息,我更喜欢通过属性访问另一个表单。除此之外,您还可以定义一个接口,该接口将包含表单之间通信所需的所有属性/方法。使用界面会更清晰,你会得到你需要的信息,不会被其他不相关的信息过载。

例如:

Interface IForm2
{
   // your properties
   string PersonName {get;}     // Just an example
   // your methods
}
class Form1: Form
{
     private IForm2 _form2;
     void Foo()
     {
         var pname = _form2.PersonName;   // Just an example
     }
}
class Form2: Form, IForm2
{
    string PersonName 
    {
         get 
         {
              return personNameTextBox.Text;
         }
    }
}