从不同形式访问控件

时间:2013-01-12 18:40:17

标签: c# winforms controls

我有一个主要表单,包含一些按钮,文本框,标签等。 在第二个表单上,我想将主表单文本框中的文本复制到第二个表单上。

尝试过:

var form = new MainScreen();
TextBox tb= form.Controls["textboxMain"] as TextBox;
textboxSecond.Text = tb.Text;

但它只会导致异常。主屏幕文本框已初始化并包含文本。 当我将鼠标悬停在form上时,我可以看到所有控件都在那里。

我做错了什么?

2 个答案:

答案 0 :(得分:1)

凤凰城重生是正确的。问题是您正在创建一个新的MainScreen,这意味着创建了新的控件,因此除非控件中的文本在表单构造函数中初始化,否则它们将为空。通常,处理此问题的方法是将第一个表单实例传递给第二个表单,如下所示:

SecondForm second = new SecondForm(this);

以第二种形式:

public SecondForm (MainForm form)
{
    // do something with form, like save it to a property or access it's controls
}

这样,第二个表单将可以访问第一个表单的控件。您可以考虑使用公共所需的属性(在设计器属性窗格中)。这样你就可以form.textboxMain.Text

答案 1 :(得分:1)

查看原始代码,您获得的NullReferenceException有两个潜在原因。首先,tb未在您提供的代码中定义,因此我不确定它是什么。

其次,TextBox textbox = form.Controls["textboxMain"] as TextBox如果找不到控件不是null,则可以返回TextBox。默认情况下,控件标有private访问者,这使我怀疑form.Controls[...]会为null成员返回private

虽然将控件标记为internal可能会解决此问题,但实际上并不是解决此问题的最佳方法,并且只会导致将来编码习惯不佳。控件上的private访问器非常好。

在表单之间共享数据的更好方法是使用public属性。例如,假设您的主屏幕上有一个名为TextBox的{​​{1}},并希望将其公开显示为其他表单:

usernameTextBox

然后您在代码中所要做的就是:

public string Username
{
  get { return usernameTextBox.Text; }
  set { usernameTextBox.Text = value; }
}

关于此解决方案的重要部分是您可以更好地控制数据如何通过属性存储。您的var form = new MainForm(); myTextBox.Text = form.Username; // Get the username TextBox value form.Username = myTextBox.Text; // Set the username TextBox value get操作可以包含逻辑,设置多个值,执行验证以及各种其他功能。

如果您正在使用 WPF ,我建议您查找 MVVM 模式,因为它允许您执行与对象状态类似的操作。