GlobalAccessSoftware icon

Getting around HybridDictionary Not Being Serializable.

GlobalAccessSoftware | PRO | 06/05/17 08:57:05 PM UTC | 0 ⭐ | 811 👁️ | Never ⏰ | []
C# |

8.13 KB

|

None

|

0 👍

/

0 👎

 
#region AppCode5 Part-3 v4.7.5.10 Jun 05 17
 
    /* This was way easier than I thought it would be,
     * (Except finally learning that a HybridDictionary
     * is not Serializable to XML and storing it as a
     * String Collection, flipping between Key & Value on the fly.)
     * Sure shows what you can do with situational awareness
     * of and reuse of existing code and so forth.
     * v4.7.4.07 Jun 04 2017
     * (c) 2011 - 2031 by John P. Edwards
     * Final Debug and Test v4.7.5.10 Jun 05 2017
     * ******************************************
     */
 
    //private static HybridDictionary Dic { get; set; }
    //// This ^ Property is in the Header as Class Global.
 
    /// <summary> Load HybridDictionary string, int
    /// from StringCollection Setting.
    /// v4.7.5.10 Jun 05 2017
    /// </summary>
    private static void LoadDic()
    {
      var flip = false;
      Object key  = "";
      var raw  = OPS.Default.RecNumDic;
      // Actually ^ a StringCollection.
      if (raw == null || raw.Count < 1) return;
 
      try
      {
        Dic = new HybridDictionary();
        foreach (Object str in raw)
        {
          flip = !flip; // Alternate between Key & Value.
          if (flip)
          { // key is already a string doesn't
            // need to be "unBoxed" in this example.
            key = str;
            continue;
          }
          int value;
          try
          { // The int32 Value needs to be
            // "unBoxed" thusly from a string.
            // But it's the same principle as with Objects,
            // & Boxing & Unboxing thereof.
            value = Convert.ToInt32(str);
          }
          catch (FormatException)
          {
            const string
              except = "FormatException",
              sender = "Inner Try Block";
              TestMessager(sender, except);
            value = -1;
          }
          if ( Dic.Contains(key)) Dic[key] = value;
          else Dic.Add(key, value);
        }
      }
      catch (ArgumentException)
      {
        const string
          except = "System.ArgumentException",
          sender = "Outter Try Block";
        TestMessager(sender, except);
      }
    }
 
    private static void TestMessager(string sender, string e)
    {
      if (Testing) MessageBox.Show(string.Format(
        "{0}\nException in LoadDic:\n\n{1}\n\n", sender, e));
    }
 
    /// <summary> Save the HybridDictionary
    /// as StringCollection.
    /// Called only from FormClosing.
    /// v4.7.5.10 Jun 05 2017
    /// </summary>
    private static void SaveDic()
    {
      SaveRecNum(true); // It should never happen after <-= but...
      if (Dic == null || Dic.Count < 1) return;
 
      var i = Dic.GetEnumerator();
      OPS.Default.RecNumDic = new StringCollection();
      while (i.MoveNext())
      {
        OPS.Default.RecNumDic.Add(i.Key.ToString());
        OPS.Default.RecNumDic.Add(i.Value.ToString());
        // Adding them two at a time because it's a KeyValue pair.
        // NOTE: The StringCollection will always be twice the size
        // of the HybridDictionary because of this. (Alternate Pairs)
      }
      OPS.Default.Save();
    }
 
    // Called only from TestButtonClick.
    private static void ViewDictionary()
    {
      if (Dic == null) return;
      var e = Dic.GetEnumerator();
      var n = 1;
      const string
        t = "Contents of Dictionary:";
      var x = "";
      while (e.MoveNext())
      {
        x += string.Format(
          "Entry #{0})\nFile: {1}\n\n" +
          "Which has a corresponding" +
          " RecNum of {2}\n\n",
            n++, e.Key, e.Value);
      }
      using (var j = new ShowMeForm(x,t))
      {
        j.Size     = AUS.Default.ViewDic_Size;
        j.Location = AUS.Default.ViewDic_Loca;
        j.ShowDialog();
        AUS.Default.ViewDic_Size = j.Size;
        AUS.Default.ViewDic_Loca = j.Location;
      }
      AUS.Default.Save();
    }
 
    /// <summary> Gets the Previous Record Number
    /// for the current data file. Defaults to first
    /// Record when none found. (Gets added in SaveRecNum)
    /// Called from AppCode1.cs from AppStart() and in the
    /// OptionsBackend.cs from LoadNewPreferences();
    /// </summary>
    private void GetRecNum()
    {
      // Never gets here unless UsePreferences is Checked.
      if (Dic == null || Dic.Count < 1) LoadDic();
      // if still null then initialize the HybridDictionary.
      if (Dic == null || Dic.Count < 1)
        Dic = new HybridDictionary(false);       
      #region Lesson Learned Here:
      // why did it reset each run as HybridDictionary?
      // Because Hybrid Dictionary is not Serializable to XML
      // so I just had to convert it to a String Collection and
      // flip them 2 at a time into the HybridDictionary on FormLoad
      // and Then convert it back to the String Collection on FormClose
      // with LoadDic() and SaveDic();
      #endregion
      if (Dic == null || Dic.Count < 1) return;
      var f = AUS.Default.RootDir +
        "\\" + AUS.Default.FileName;
      _wasAtNum =
        AUS.Default.RecordNum =
          Dic.Contains(f) ? (int)Dic[f] : -1; // v4.7.5.10
      CheckDic();
      AUS.Default.Save();
    }
 
    private static bool UsePreferences(bool which)
    {
      var title = ARS.IF_UsePrefTitle1;
        //"Turn on Preferences?";
      var text  = ARS.IF_UsePrefText1;
        //"This feature is only available when\n" +
        //"the Folder Preference Setting is ON.\n\n" +
        //"Would you like to turn it on Now?";
      if (!which)
      {
        title = ARS.IF_UsePrefTitle2;
        text  = ARS.IF_UsePrefText2;
        //"Turning on the Alternate Folder\n" +
        //"Finder in Options is a Key feature too.\n\n" + todo remnants.
        //"Would you like to turn it on now as well?\n" +
        //"(Recomended)\n";
      }
      return
        AppStatic.YesNoDialog(text, title, 1);
    }
 
    /// <summary> Either add or change existing value.
    /// Checks for Object in HybridDictionary and changes
    /// the value or adds the key and value to the Collection.
    /// Called from SaveDic(); here (Which is called from FormClosing();)
    /// and from OptionsBackend.cs from LoadNewPreferences();
    /// </summary>
    private static void SaveRecNum(bool auto)
    {
      if (!OPS.Default.UsePreferences)
      {
        if (auto) return;
        if (!UsePreferences(true)) return;
        OPS.Default.UsePreferences = true;
        if (!OPS.Default.AlternateFolderFinder
          && UsePreferences(false))
            OPS.Default.AlternateFolderFinder = true;
        OPS.Default.Save();
      }
      if (Dic == null)
      { 
        Dic = new HybridDictionary(false);
        if (Dic == null)
        {
          if (Testing && !auto)
            MessageBox.Show(ORS.IF_SaveRecNum_NULL);
          return;
        }
      }
      var key   = AUS.Default.RootDir +
        "\\"  +   AUS.Default.FileName;
      var index = AUS.Default.RecordNum =
        CurrentRecord - 1;
      if (Dic.Contains(key)) Dic[key] = index;
      else Dic.Add(key, index);
      AUS.Default.Save();
      CheckDic();
    }
 
    /// <summary> Check Dictionary and Verify Data there. 
    /// </summary>
    private static void CheckDic()
    {
      foreach (string ffn in Dic.Keys)
      {
        var dir  = Path.GetDirectoryName(ffn);
        if (dir == null) return;
        if (Directory.Exists(dir)
          && HasDataFiles(dir)
          && File.Exists(ffn))
        {
          if (!Dic.Contains(ffn))   Dic.Add(ffn, 0);
        }
        else if (Dic.Contains(ffn)) Dic.Remove(ffn); // OUCH!
      }
    }
 
    /// <summary> Local Call that Calls OptionsForm Method.
    /// Mostly created so this shows up in this Class. 
    /// </summary>
    /// <param name="dir"></param>
    /// <returns></returns>
    private static bool HasDataFiles(string dir)
    {
      return OptionsForm.HasDataFiles(dir);
    }
#endregion AppCode5 Part-3 v4.7.5.10 Jun 05 17
    //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\

Comments

  •  icon
    01/01/70 12:00:00 AM UTC
    Plain Text |

    0 B

    |

    👍

    /

    👎