简体   繁体   中英

C# WinForms Passing Dictionary from Static Class To Non-Static Form Class

If I have a dictionary in a static class that gets updated randomly with data, how do I then pass this dictionary to the main form to display it in a grid view if the mainform is not static? Surely if I create a new instance of the mainform I will have multiple mainforms everytime I try and do this (every 15 seconds) and I will lose data......right?

Leaving out the comments on your design (urgh... sorry couldn't help that) the cheap and easy thing is to give your static updater your main form and let the static class update your form manually.

public static class OmfgUpdater
{
  private static MyForm _mainForm;
  public static void RegisterForm(MyForm form)
  {
    _mainForm = form;
  }

  /*however this is done in your class*/
  internal static void Update(Dictionary<string,string> updates)
  {
    _mainForm.Update(updates);
  }
}

public class MyForm : Form
{

  public MyForm()
  {
    OmfgUpdater.RegisterForm(this);
  }

  public void Update(Dictionary<string,string> updates)
  {
    /* oh look you got updates do something with them */
  }
}

Disclaimer 1 : The statement in your question : "if I create a new instance of the mainform I will have multiple mainforms everytime I try and do this (every 15 seconds) and I will lose data......right?" is not at all clear to me. I'm going to answer here by interpreting your statement you want a static Dictionary as meaning you want one-and-only-one no matter how many other forms might be launched by one application instance.

Disclaimer 2 : Also the code I show here is meant to contrast with Will's answer where the static class updates the main form. And the answer here does not address dynamic linkage (databinding) at all : there's no code here for the user making a change on the form in the DataGridView, and having that back-propagate to update the underlying dictionary.

Assuming you want one-and-only-one Dictionary per application instance : If you have a public static class that holds a public static instance of a Dictionary like :

public static class DictionaryResource
{
    // make dictonary internal so the only way to access it is through a public property
    internal static Dictionary<string, int> theDictionary = new Dictionary<string, int>();

    // utility methods :

    // 1. add a new Key-Value Pair (KVP)
    public static void AddKVP(string theString, int theInt)
    {
        if (! theDictionary.ContainsKey(theString))
        {
            theDictionary.Add(theString, theInt);
        }    
    }

    // 2. delete an existing KVP
    public static void RemoveKVP(string theString)
    {
        if (theDictionary.ContainsKey(theString))
        {
            theDictionary.Remove(theString);
        }
    }

    // 3. revise the value of an existing KVP
    public static void ChangeDictValue(string theString, int theValue)
    {
        if(theDictionary.ContainsKey(theString))
        {
            theDictionary[theString] = theValue;
        }
    }

    // expose the internal Dictionary via a public Property 'getter
    public static Dictionary<string,int> TheDictionary
    {
       get { return theDictionary; }
    }
}

At that point you can achieve dynamic updating of the contents of the Dictionary on a Form either through DataBinding techniques, or by defining custom events in the methods in the static class that are raised : these event are then subscribed to on the Form, and when you intercept these changes in the Form, you can then take action to update whatever representation you have on the Form.

Here's an example of defining a custom event in the static class :

    // delegate signature
    public delegate void addKVP(string sender, int value);

    // delegate instance
    public static event addKVP KeyValuePairAdded;

    // delegate run-time dispatcher
    public static void OnKVPAdded(string sender, int theInt)
    {
      if (KeyValuePairAdded != null)
      {
          KeyValuePairAdded(sender, theInt);
      }
    }

Then, as an example of how you subscribe to that custom event in a Form : in this case in the 'Load event :

        DictionaryResource.KeyValuePairAdded += new DictionaryResource.addKVP(DictionaryResource_KeyValuePairAdded);

Where you have defined the handler for the event ... in the Form ... as :

    private void DictionaryResource_KeyValuePairAdded(string theString, int theInt)
    {
        Console.WriteLine("dict update : " + theString + " : " + theInt);
    }

A typical validation test executed in the Form's code might have calls like :

        DictionaryResource.AddKVP("hello", 100);
        DictionaryResource.AddKVP("goodbye", 200);

Obviously, you would modify that code in the Form's handler that justs prints a report to the console now to modify your DataGridView on the Form, or whatever other representation you are creating on the Form(s).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM