【问题标题】:Passing Values Between C# Winforms Working Intermittently在间歇工作的 C# Winforms 之间传递值
【发布时间】:2012-01-31 11:47:40
【问题描述】:

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

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

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

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

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

public MainForm MainForm;

然后我尝试像这样传递值:

 MainForm.textBox1.Text = txt_FileName.Text;

注意:所有在表单之间传递值的TextBox和Label控件都是public

有人遇到过这个吗?或任何想法? .

【问题讨论】:

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

标签: c# winforms


【解决方案1】:

您需要确保所有表单都已实例化(通过 new 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 中)。它还可以更好地封装您的程序,因为无法从外部访问控件。

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

      例如:

      SecondForm secForm2 = new SecondForm();
      secForm2.textBox1.Text = txt_FileName.Text
      

      因此,如果您将值从 SecondForm 传递给 ThirdForm:

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

      【讨论】:

        猜你喜欢
        • 2011-03-05
        • 1970-01-01
        • 1970-01-01
        • 2022-09-29
        • 2016-12-03
        • 2023-03-09
        • 1970-01-01
        • 2013-12-02
        相关资源
        最近更新 更多