Paul Bouch
Paul Bouch

Reputation: 11

C# Creating a global object of a class for use on multiple forms

I want to create a multiple objects of a class, edit them on one form and then use those objects on multiple forms. Hopefully the code below will try and highlight the problem.

I created a class as such...

public class Player
{
        public string name;
        public int goals;        
}

On Form1 I have created tom and dan, and added buttons that will increase their goal count when pressed.

public partial class Form1 : Form
{

    Player tom = new Player()
    {
        name = "Tom",
        goals = 5
    };

    Player dan = new Player()
    {
        name = "Dan",
        goals = 7
    };

    public void UpdateForm()
    {
        label1.Text = tom.name;
        label2.Text = dan.name;
    }


    public Form1()
    {
        InitializeComponent();
        UpdateForm();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        tom.goals += 1;
    }

    private void button2_Click(object sender, EventArgs e)
    {
        dan.goals += 1;
    }
}

I then want to be able to display their names and the new number of goals on form2. The problem I have is that those objects don't exist in that context.

{
public partial class Form2 : Form
{
       public void UpdateForm2()
    {
        label1.Text = tom.name;
        label2.Text = tom.goals;
        label3.Text = dan.name;
        label4.Text = dan.goals;
    }


    public Form2()
    {
        InitializeComponent();
        UpdateForm2();
    }
}
}

How do I make those objects global and editable between forms? I've tried to find an answer but haven't found one that quite matches this use case. I would appreciate any help and advice.

Upvotes: 1

Views: 4054

Answers (6)

Connell.O'Donnell
Connell.O'Donnell

Reputation: 3693

It seems like you need a service class that holds a List<Person>. Then just have your two forms share the same instance of that service. Or the lazy option is to make the service a static class.

Update

You could also consider implementing the Observer pattern in the service.

http://www.dofactory.com/net/observer-design-pattern

Upvotes: 0

CodingYoshi
CodingYoshi

Reputation: 27009

Your Form1 class is like any other class. Therefore, you can create 2 properties in it:

public partial class Form1 : Form
{
    public Player Tom { get; private set; }
    public Player Dan { get; private set; }

    this.Tom = new Player()
    {
        name = "Tom",
        goals = 5
    };

    this.Dan = new Player()
    {
        name = "Dan",
        goals = 7
    };    

    // The rest of your code
}

In Form2 introduce a property:

public partial class Form2 : Form
{
    public Form1 CallingForm {get; set;}   
    public Form2()
    {
        InitializeComponent();
        UpdateForm2();
    }
}

Set that property before you show the second form like this (put this code in your first form):

Form2 f2 = new Form2();
f2.CallingForm = this;

Then in the second form you can access the players like this:

label1.Text = CallingForm.Tom.name;

If you have more players then create a List<Player> property instead.

Some other notes

Try following the .NET naming conventions and instead of public fields, use properties. Properties can be used for databinding and encapsulation, validation and has other benefits as well.

public class Player
{
    private int goals;
    public string Name {get; set;}
    public int Goals 
    {
        get { return this.goals; }
        set 
        {
            if (value < 0)
            {
                throw new ArgumentException("Goals cannot be less than 0.");
            } 
            this.goals = value;
        }  
     }      
}

Upvotes: 2

JMadelaine
JMadelaine

Reputation: 2964

Think about encapsulation. Your Form2 cannot access the instantiated class objects because they are contained within Form1.

When you write the following:

label1.Text = tom.name;

The compiler is looking for the object Form2.tom, but it doesn't exist.

You have to tell it where to look, like so:

label1.Text = Form1.tom.name;

To make these objects available to all chosen classes without using the Form1 prefix, the chosen classes would have to be subclasses of Form1. Other than that, you'd have to refer back to them in the way I explained previously.

Upvotes: 0

Yes , must transport data new form. Meybe use send parameter to Form2 contructor parameter or use form2 Set Method.

For Example :

      private readonly Player _tom;
      private readonly Player _dan;

     public Form2(player tom, player dan) // or use List<Player> parameter
        {
            InitializeComponent();
            _tom = tom;
            _dan = dan;
        }

another way

// Form2.cs

private Player _tom;
private Player _dan;

public void SetPalyers(Player tom, Player dan)
{
  _tom = tom;
 _dan = dan;
}

Upvotes: 0

Rick
Rick

Reputation: 1274

You can pass the list of players in the constructor of the second form.

Upvotes: 0

Prajwal
Prajwal

Reputation: 4000

You need to know the concept of namespace. If you create an object in namespace of one form, you cannot use that particular object without referring that particular form.

So far what I can see, you've created two instances of object player in form namespace. But that's not there in form2 namespace. Hence you're getting that error.

You can use many methods commonly used to update such as

  • calling child window's method to update the values.
  • using mediator
  • adding an event listener to form2 on value change.

Using a global instance of an object instance or a static object is not a best practice.

Upvotes: 0

Related Questions