C# winform: Accessing public properties from other

2020-01-29 11:18发布

问题:

I am trying to understand whats the difference between a static and public properties. But when I tried to access my public property 'Test' in other form it says 'null'.

Heres Form1:

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();
    }
}

Here's 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;
    }
}

To check the value of 'Test' in Form1, I put a breakpoint to this line:

label1.Text = frm1.Test;

But the value is 'null'.

Please help me how can I access public properties to other forms.

And BTW I tried to make this public property be a 'public static'. I can access this using this:

Form1.Test

But I noticed that I can change 'Test' value from Form2 which I don't want to happen. That's why I am trying to use public property but with no luck. Can somebody clarify me these things. Thanks for all your help guys!

EDIT: (For follow up question) 

Sir John Koerner's answer is the best answer for my question. But I have a follow up question, I tried to make these 'test' properties to be a 'static', and I noticed that even if I make this property a static or public property, it still can be edit in Form2. To make myself clear here's a sample:

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();
    }
}

After Form2 closed, I tried to break again in Form1_Load to check value of 'Test', and it was changed! How can I make a public property in Form1 to readOnly in Form2 and cannot be editted? Please clarify to me. Thanks a lot guys!

回答1:

Your property is an instance variable, so the value can be different across different instances of Form1.

If you are trying to access instance variables from a parent form, the easiest way to do that is to pass Form1 in to the constructor of 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;
    }
}

Then when you create a new Form2 from Form1, you can do this:

Form2 frm2 = new Form2(this);

If you want your property to be read only, you can simply not specify a setter:

public string Test
{
    get { return _test; }
}


回答2:

Use of this method 'static'

At first Control label property Modifiers=Public

in Program code below

public static Form1 frm1 = new Form1();
public static Form2 frm2 = new Form2();

in Form1 code below

Program.frm2.show();

in Form2 code below

label1.Text=Program.frm1.text; 


回答3:

The frm1 not your main form object. It is newly created object where property Test initializes when it loads (in Form1_Load event handler).



回答4:

The first instance of Form1 shows an instance of Form2, and then Form2 creates another instance of Form1. This could work, but you set _test in the Form.Load event, which:

Occurs before a form is displayed for the first time.

You do not show the instance of Form1 you're trying to read Test from, so its Load event will not occur and Test remains null.

You could add a constructor overload or property to pass the Form1 reference as @JohnKoerner mentions, but I would prefer to only pass the required variable, perhaps even encapsulated in an event, to reduce coupling. Form2 usually doesn't need to know all about Form1.



回答5:

public

The type or member can be accessed by any other code in the same assembly or another assembly that references it.

static

The static modifier on a class means that the class cannot be instantiated, and that all of its members are static. A static member has one version regardless of how many instances of its enclosing type are created.

A static class is basically the same as a non-static class, but there is one difference: a static class cannot be externally instantiated. In other words, you cannot use the new keyword to create a variable of the class type. Because there is no instance variable, you access the members of a static class by using the class name itself.

However, there is a such thing as a static constructor. Any class can have one of these, including static classes. They cannot be called directly & cannot have parameters (other than any type parameters on the class itself). A static constructor is called automatically to initialize the class before the first instance is created or any static members are referenced. Looks like this:

static class Foo() { static Foo() { Bar = "fubar"; }

public static string Bar { get; set; }

}

Static classes are often used as services, you can use them like so:

MyStaticClass.ServiceMethod(...);