C#winform:从其他forms访问公共属性以及静态和公共属性之间的区别
我试图了解静态属性和公共属性之间的区别。 但是当我试图以其他forms访问我的公共财产“测试”时,它会说’null’。
继表格1:
public partial class Form1 : Form { public Form1() { InitializeComponent(); } private string _test; public string Test { get { return _test; } set { _test = value; } } private void Form1_Load(object sender, EventArgs e) { _test = "This is a test"; } private void button1_Click(object sender, EventArgs e) { Form2 frm2 = new Form2(); frm2.Show(); } }
这是Form2:
public partial class Form2 : Form { public Form2() { InitializeComponent(); } private void Form2_Load(object sender, EventArgs e) { Form1 frm1 = new Form1(); label1.Text = frm1.Test; } }
要检查Form1中“Test”的值,我在此行中添加了一个断点:
label1.Text = frm1.Test;
但价值是’无效’。
请帮助我如何访问其他表单的公共属性。
而且我试图让这个公共财产成为一个“公共静态”。 我可以使用这个来访问它:
Form1.Test
但我注意到我可以从Form2更改“Test”值,我不想发生这种情况。 这就是我试图使用公共财产但没有运气的原因。 有人可以向我澄清这些事情。 谢谢你们的帮助!
EDIT: (For follow up question)
John Koerner爵士的回答是我问题的最佳答案。 但我有一个跟进问题,我试图让这些’测试’属性成为’静态’,我注意到即使我将此属性设置为静态或公共属性,它仍然可以在Form2中编辑。 为了使自己清楚这里是一个样本:
public partial class Form2 : Form { private Form1 f1; public Form2(Form1 ParentForm) { InitializeComponent(); f1 = ParentForm; } private void Form2_Load(object sender, EventArgs e) { label1.Text = f1.Test; } private void button1_Click(object sender, EventArgs e) { f1.Test = "This test has been changed!"; this.Close(); } }
在Form2关闭后,我尝试在Form1_Load中再次中断以检查’Test’的值,并且它已被更改! 如何在Form1中将公共属性设置为在Form2中readOnly并且不能编辑? 请向我澄清一下。 非常感谢!
您的属性是一个实例变量,因此Form1
不同实例的值可能不同。
如果您尝试从父窗体访问实例变量,最简单的方法是将Form1传递给Form2的构造函数。
public partial class Form2 : Form { private Form1 f1; public Form2(Form1 ParentForm) { InitializeComponent(); f1 = ParentForm; } private void Form2_Load(object sender, EventArgs e) { label1.Text = f1.Test; } }
然后,当您从Form1创建一个新的Form2时,您可以这样做:
Form2 frm2 = new Form2(this);
如果您希望您的财产是只读的,您可以不指定一个setter:
public string Test { get { return _test; } }
使用此方法’静态’
起初控制标签属性Modifiers = Public
在下面的程序代码中
public static Form1 frm1 = new Form1(); public static Form2 frm2 = new Form2();
在下面的Form1代码中
Program.frm2.show();
在下面的Form2代码中
label1.Text=Program.frm1.text;
frm1
不是你的主要表单对象。 它是新创建的对象,其中属性Test
在加载时初始化(在Form1_Load
事件处理程序中)。
Form1
的第一个实例显示Form2
的实例,然后Form2
创建另一个 Form1
实例。 这可能有效,但您在Form.Load
事件中设置Form.Load
,其中:
在第一次显示表单之前发生。
您没有显示您尝试读取Test
的Form1
实例,因此不会发生其Load
事件,并且Test
仍为null
。
你可以添加一个构造函数重载或属性来传递Form1引用,如@JohnKoerner所提到的那样,但我更愿意只传递所需的变量,甚至可能封装在一个事件中,以减少耦合。 Form2
通常不需要知道Form1
全部内容。
上市
类型或成员可以由同一程序集中的任何其他代码或引用它的另一个程序集访问。
静态的
类上的static修饰符意味着该类无法实例化,并且其所有成员都是静态的。 静态成员具有一个版本,无论其封闭类型的实例数量是多少。
静态类与非静态类基本相同,但有一个区别:静态类不能在外部实例化。 换句话说,您不能使用new关键字来创建类类型的变量。 因为没有实例变量,所以可以使用类名本身访问静态类的成员。
但是,有一个静态构造函数。 任何类都可以包含其中一个,包括静态类。 它们不能直接调用,也不能有参数(除了类本身的任何类型参数)。 在创建第一个实例或引用任何静态成员之前,会自动调用静态构造函数来初始化类。 看起来像这样:
static class Foo(){static Foo(){Bar =“fubar”; }
public static string Bar { get; set; }
}
静态类通常用作服务,您可以像这样使用它们:
MyStaticClass.ServiceMethod(…);