在间歇工作的C#Winforms之间传递值

在间歇工作的C#Winforms之间传递值,c#,winforms,C#,Winforms,我试图在几个winforms之间传递值,我总共有6个winforms,用户将循环使用。我使用TextBox和Label控件在表单之间传递值 当我打开主winform,然后单击按钮加载第二个winform时,一切正常(我可以将值传递给第一个窗体)。我的问题是,一旦我将用户引导到另一个表单并this.Hide()当前(第二个Winform),然后尝试使用第三个窗体将值传递给第一个窗体,我得到以下错误: 对象引用未设置为对象的实例 我很困惑,因为应该传递值的控件正在将值传递给第一个表单,而该控件不是N

我试图在几个winforms之间传递值,我总共有6个winforms,用户将循环使用。我使用TextBox和Label控件在表单之间传递值

当我打开主winform,然后单击按钮加载第二个winform时,一切正常(我可以将值传递给第一个窗体)。我的问题是,一旦我将用户引导到另一个表单并
this.Hide()当前(第二个Winform),然后尝试使用第三个窗体将值传递给第一个窗体,我得到以下错误:

对象引用未设置为对象的实例

我很困惑,因为应该传递值的控件正在将值传递给第一个表单,而该控件不是
NULL

我使用相同的代码将所有表单连接在一起

public MainForm MainForm;
然后我尝试这样传递值:

 MainForm.textBox1.Text = txt_FileName.Text;
注意:在表单之间传递值的所有文本框和标签控件都是
public

有人碰到这个吗?或者有什么想法?
.

您需要确保所有表单都已实例化(通过新的MyForm1()…)。仅仅声明一个MainForm类型的变量不会创建一个表单实例——您必须这样做。我的猜测是,当您尝试访问控件时,其中一个窗体尚未创建

这是不使用公共控件的另一个原因(也请参见我的评论),因为控件的生命周期与窗体的生命周期相关。最好隐藏控件,不让公众访问,并通过数据对象将数据发送到表单——表单将所有这些值设置为自己的控件。这也使得验证更加容易,因为控件的值只能设置为表单允许的值。如果从外部设置控制值,则在所有场景中都很难验证它们

我假设您正在尝试使用与向导类似的模式表单,在向导中,用户按照清晰的路径从一个表单转到下一个表单。如果是这样,您可以这样做:

// Data class to set data in Form2
internal class Form2Data
{
    public string Name;
    ...
}

...

internal class Form2 : Form
{
    public static DialogResult ShowDlg ( Form2Data oData )
    {
        Form2 oFrm = new Form2 ();

        oFrm.SetData ( oData );
        DialogResult nResult = oFrm.ShowDialog ();

        if ( nResult == DialogResult.Ok )
            oFrm.GetData ( oData );

        return ( nResult );
    }

    private void SetData ( Form2Data oData )
    {
        // Set control values here
    }

    private void GetData ( Form2Data oData )
    {
        // Read control values here
    }
}

...
// You call this as such:
Form2Data oData = new Form2Data ();
oData.Name = "...";

DialogResult nResult = Form2.ShowDlg ( oData );

// after the call, oData should have updated values from Form2
if ( nResult == DialogResult.Ok )
{
    // show your next form in a similar pattern - set up data
    // call form's static method to pass it and then wait for
    // the form to finish and return with updated data.
}

在其他表单中也必须使用类似的模式。这确实需要更多的工作,因为您需要为所有表单设置不同的数据对象,但通过这种方式,您可以轻松地在显示表单之前和之后(在SetData和GetData中)进行验证。它还可以更好地封装程序,因为无法从外部访问控件。

您应该使用表单的实例值传递值

例如:

SecondForm secForm2 = new SecondForm();
secForm2.textBox1.Text = txt_FileName.Text
因此,如果将值从SecondForm传递到ThirdForm:

ThirdForm thiForm = new ThirdForm();
thiForm.textBox1.Text = textBox1.Text

.Net 2.0及更高版本为windows窗体提供了一个称为“默认实例”的功能,它为您提供了一个与类型同名的实例。此功能的目的是与从旧vb6应用程序迁移的代码兼容。如果您不是从旧的vb应用程序迁移,通常最好避免使用默认实例。他们会给你带来麻烦,就像你现在这样。相反,创建一个变量来保存你自己构建的表单实例。

显然有些东西是NULL,所以你需要在错误的上下文中提供一些代码。你应该考虑使用简单的数据对象,这些数据对象在表单之间传递,而不是公共控件。所有表单中的所有控件都应该是私有的(如果从表单派生,则可能会受到保护)。一般来说,UI对象中的公共控件会导致未来的灾难。即使你让它工作,你将有一个维护噩梦与此设置。