Advertisement

[Visual C#] Help with passing an object between forms

Started by March 27, 2015 02:41 AM
2 comments, last by jpetrie 9 years, 10 months ago

I'll try to explain best as I can:

I am trying to pass on object between forms. Basically, Form1 is an RPG-like character creation screen that creates a character object. I am trying to pass that object to a second form where you can view a character description in a rich text box. I am getting a 'does not exist in this context' error when i try to access that object. Any solutions?

You have several options:


class Form1 : Form
{
  void OpenSecondForm(object thingy)
  {
    var form2 = new Form2(thingy);  // Option 1:  Pass it via the constructor when you create your second form.

    form2.Thingy = thingy; // Option 2:  Set a public field.

    form2.ThingyProperty = thingy; // Option 3: Set a public property.

    form2.SetThingy(thingy); // Option 4:  Call a function to set it.

    // NOTE: You only need to use one of the four options.  I listed them all at once to reduce the amount of typing.

    form2.Show();
  }
}

class Form2 : Form
{
  public object Thingy;

  public object ThingyProperty // Generally you would not make a property when the field is also public - this is for demonstration only.
  {
    get { return Thingy; }
    set { Thingy = value; }
  }
  
  public Form2(object thingy)
  {
    Thingy = thingy;
  }

  public void SetThingy(object thingy)
  {
    Thingy = thingy;
  }
}
Advertisement

Well you could add a static class to hold character creation in and all form can access this data without having a reference. For example


public static class CharacterCollection
    {
        public static Dictionary<string, Character> Characters = new Dictionary<string, Character>();

        private static string _currentCharacter = string.Empty;

        static CharacterCollection()
        {
        }

        public static Character SelectCurrent()
        {
            if (Characters.ContainsKey(_currentCharacter) == true)
            {
                return Characters[_currentCharacter];
            }

            return null;
        }

        public static void Add(Character character)
        {
            if(Characters.ContainsKey(character.Name) == false)
            {
                Characters.Add(character.Name, character);

            }
            else
            {
                Characters[character.Name] = character;
            }
        }

        public static bool SetCurrent(string name)
        {
            if (Characters.ContainsKey(name) == true)
            {
                _currentCharacter = name;
                return true;
            }

            return false;
        }
    }

Usage:

FormA:


            Character newPlayer = new Character("PlayerA", 1, 1);

            CharacterCollection.Add(newPlayer);

            CharacterCollection.SetCurrent(newPlayer.Name);

FormB


   Character player = CharacterCollection.SelectCurrent();

This will give you the ability to navigate multiple forms without having to pass a reference to each form or the game, just grab it out of the collection.

Using a globally-accessible static collection is not a great solution, especially compared to the previously offered solution of "pass the data you need." That solution makes the dependency explicit and does not bring in the whole messy can-of-worms that global state can involve. Having to "pass the data everywhere" (where "everywhere" is "almost all other classes" is a useful thing; if you're doing it too much it's a sign you may need to improve the dependency relationships between the interfaces in your designs).

Also, as an aside, the pattern of "if (dictionary.ContainsKey(key) { ...dictionary[key]... }" is inefficient since it does the lookup twice; consider TryGetValue instead.

This topic is closed to new replies.

Advertisement