简体   繁体   English

C#WinForms将字典从静态类传递到非静态表单类

[英]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? 当然,如果我创建该主窗体的新实例,则每次尝试执行此操作(每15秒)都会有多个主窗体,并且我将丢失数据……对吗?

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?" 免责声明1:您问题的陈述:“如果我创建一个新的主窗体实例,则每次尝试执行此操作(每15秒),我都会拥有多个主窗体,并且我将丢失数据……对吗?” 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. 我将在这里通过将您想要一个静态Dictionary的语句解释为您的意思,这意味着无论一个应用程序实例可能启动多少种其他形式,您都希望一个且仅一个。

Disclaimer 2 : Also the code I show here is meant to contrast with Will's answer where the static class updates the main form. 免责声明2:另外,我在此处显示的代码旨在与Will的答案形成对比,Will的答案是静态类更新主要形式。 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. 而且这里的答案根本没有解决动态链接(数据绑定):这里没有代码供用户在DataGridView中的表单上进行更改,并使该反向传播来更新基础字典。

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. 到那时,您可以通过DataBinding技术或通过在引发的静态类的方法中定义自定义事件来实现Form上Dictionary内容的动态更新:然后在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 : 然后,以有关如何在Form中订阅该自定义事件的示例为例:在本例中为'Load事件:

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

Where you have defined the handler for the event ... in the Form ... as : 您在Form中将事件处理程序定义为...的位置:

    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). 显然,您将在Form的处理程序中修改该代码,该处理程序现在会将报告打印到控制台,以修改Form上的DataGridView或您正在Form上创建的任何其他表示形式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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