2012-01-31 31 views
0

我试图通过几个WinForms之间的值,我总共有6个WinForms,用户将循环。我使用TextBox和Label控件在窗体之间传递值。C#Winforms之间传递值间歇工作

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

Object reference not set to an instance of an object.

我困惑,因为应该通过值的控制传递值的第一个窗体不是NULL

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

public MainForm MainForm; 

然后我试图通过像这样的价值观:

MainForm.textBox1.Text = txt_FileName.Text; 

注:所有可在形式之间传递值的文本框和标签控件public

人遇到这个?或者任何想法? 。

+1

显然有些东西是空的,所以你需要向我们提供一些错误上下文中的代码。 – ChaosPandion 2012-01-31 03:29:29

+2

您应该考虑使用在表单之间传递的简单数据对象,而不是公共控件。所有表单中的所有控件都应该是私人的(或者如果您从表单中获得的话可能会受到保护)。一般来说,用户界面对象中的公共控件是灾难发展的秘诀。 即使你得到这个工作,你会有这个设置的维修噩梦。 – xxbbcc 2012-01-31 03:29:48

回答

1

您需要确保所有表单都已实例化(通过新的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中)之前和之后轻松地进行验证。它还能更好地封装你的程序,因为控制不能从外部访问。

0

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

例如:

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

所以如果你通过从SecondForm价值ThirdForm:

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

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