直列つなぎ。 -とある発達障害者の記録

知識と知識を繋ぐためのblog。 広汎性発達と診断されました。ぜんぜん役に立ってないけど。月収13万円、家賃4万円で生活するひつじ人間。

XMLクラスを使用して設定の保存と読み込みを行う

 
 概要
  つい最近更新された
   C#で付箋紙を作る(第四回目) データの数だけ付箋紙を起動する  
  というエントリを利用して設定のloadとsaveを行うアルゴリズムを考える。本音を言うとかなり助かる。でも、スタンドアロン型では無理があるとおもうんだよねー。 多重起動をいくつもやるのと同じなわけで。 処理が重いしメモリも食う。 最終的にIE並みに重くなると思う。
 

特にload時にこれをやるのは低スペックPCでは適さない。
 作者の考えは知らないが、C# にはopenFormsプロパティが実装されており、これにより明示的なインスタンス化無しで、nameプロパティや番号で各フォームにアクセスが可能になっている。 
 
     Windowsフォームでフォームのコレクションを使用するには?
                         動作確認済み。
     [C#]開いているフォームインスタンス参照     



 ・・・という訳で、オレは不可視のメインフォーム経由で行おうと思う。
 目的が同じでも、アプローチが異なるとどうなるのか。


 今回のサンプルでは、XMLファイル内には取得したファイル名を使い、リッチテキストファイルのloadを行う事にする。
フォント情報はrtfファイル内で扱うため、わざわざXML内に組み込む必要がない。  




 【処理】
 a. クラスに格納したXMLエレメントをシリアライズして保存(XMLファイルとして保存)
 逆にデシリアライズして読み込みという処理を行う。
 
 なお、シリアライズとは、プログラムがメモリ上に存在するデータを保存出来るように変換する処理の事。


 load時
      private void Form1_Load(object sender, EventArgs e)
        {
            setCurrent = Directory.GetCurrentDirectory();
          
        }


  用意するXMLクラス
   [XmlRoot("Sticky")]
        public class StickyData
        {
          
            public string FileName { get; set; }
       
            public int Width { get; set; }
     
            public int Height { get; set; }
    
            public int Top { get; set; }
        
            public int Left { get; set; }
    
            public Color RTFColor { get; set; }
          
          
        }

   /// <summary>
        /// StickyDataをジェネリックリスト化するクラス
        ///つまり連続したXMLリストを作る
  /// </summary>
        [XmlRoot("Stickys")]
        public class StickyList
        {
            [XmlElement("Sticky")]
            public List<StickyData> DataList { get; set; }
        }





 b-1. ディレクトリ下にあるファイル名(rtf)を列挙 (button1)


スコープ外
    string setCurrent;
        StickyList SL;
        StickyData SD;


        /// <summary>
        /// カレントディレクトリ下にある”Data”フォルダ内のファイル名を列挙
        /// </summary>
 private void button1_Click(object sender, EventArgs e)
        {

  setCurrent = Directory.GetCurrentDirectory();       
            string[] files = Directory.GetFiles(setCurrent +"\\Data\\", "*.rtf", SearchOption.TopDirectoryOnly);

  ///

            foreach (string filename in files)
            {
                string s = Path.GetFileName(filename);
                listBox1.Items.Add(s);



                SL.DataList.Add(SD);  //SD内は正常に取得できている 下記”不具合”参照
          //Sticky List にStickyDataを追加する。
            }
   }


 b-2
   上記で取得したファイル名をXMLとして保存 (button 2)
   
 private void button2_Click(object sender, EventArgs e)
        {
            var serializer = new XmlSerializer(typeof(StickyList));
            //"sticky Data"をシリアライズクラスを初期化(インスタンス化)


            var sw = new StreamWriter(@"Sticky.xml", false, new UTF8Encoding(false));
            serializer.Serialize(sw, SL);  //変数”SL”内は最後に取得したファイル名に統一されてしまう。
            //シリアライズ

            sw.Close();
  }

  不具合
   最後のファイル名しか反映されない。
  Form1.rtf ~ Form4.rtfがある場合、Form4.rtfしかファイル名として保存されない。
 (要素数.countは反映される)

  SD内は正常に取得できている
  

  出力結果 
   <?xml version="1.0" encoding="utf-8"?>
<Stickys xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Sticky>
    <FileName>Form4.rtf</FileName>
    <width>0</width>
    <height>0</height>
    <top>0</top>
    <left>0</left>
    <ForeColor />
  </Sticky>
  <Sticky>
    <FileName>Form4.rtf</FileName>
    <width>0</width>
    <height>0</height>
    <top>0</top>
    <left>0</left>
    <ForeColor />
  </Sticky>
  <Sticky>
    <FileName>Form4.rtf</FileName>
    <width>0</width>
    <height>0</height>
    <top>0</top>
    <left>0</left>
    <ForeColor />
  </Sticky>
  <Sticky>
    <FileName>Form4.rtf</FileName>
    <width>0</width>
    <height>0</height>
    <top>0</top>
    <left>0</left>
    <ForeColor />
  </Sticky>
</Stickys>
 
 解法
   foreach内でその都度new する必要がある。
   
               foreach (string filename in files)
            {
   
                string s = Path.GetFileName(filename);
                listBox1.Items.Add(s);


           var SD = new StickeData();  //その都度初期化

                SL.DataList.Add(SD);  //SD内は正常に取得できている 下記”不具合”参照
          //Sticky List にStickyDataを追加する。
            }
   

  質問
   ジェネリッククラスに要素を追加すると、最後のファイル名のみ反映されてしまう    
        > ListへのaddはSDのデータではなく、SDへのポインタがaddされるだけです。
                                        とのこと。
 




 b-3 残りのプロパティ(width,Height,top,Left,ForeColor)をXMLとして保存 (button3)


  Color情報のセット
        private void Form1_Load(object sender, EventArgs e)
        {
            setCurrent = Directory.GetCurrentDirectory();

            string[] ColorNames = { "AliceBlue","Beige","CabetBlue", "DarkGray"};

            foreach (string colorSt in ColorNames )
            {
                listBox1.Items.Add(colorSt);
            }

        }
  
    private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            if((string)listBox1.SelectedItem == "AliceBlue")
            {
                richTextBox1.BackColor = Color.AliceBlue;
            }
             else if ((string)listBox1.SelectedItem == "Beige")
            {
                richTextBox1.BackColor = Color.Beige;


            }
            else if ((string)listBox1.SelectedItem == "CabetBlue")
            {
                richTextBox1.BackColor = Color.CadetBlue;


            }

            else if ((string)listBox1.SelectedItem == "DarkGray")
            {
                richTextBox1.BackColor = Color.DarkGray;


            }

 
 ------------------------------------------

        /// <summary>
        /// 残りのプロパティを保存
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button3_Click(object sender, EventArgs e)
        {
            var SD = new StickyData();
             SL = new StickyList();
            SL.DataList = new List<StickyData>();
            //データリスト初期化

            SD.FileName = Name+ ".rtf";
            SD.Height = Height;
            SD.Width = Width;
            SD.Top = Top;
            SD.Left = Left;
            SD.BackColor = richTextBox1.BackColor.Name;

            SL.DataList.Add(SD);


        }
出力結果
<?xml version="1.0" encoding="utf-8"?>
<StickyList xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Sticky>
    <FileName>Form1.rtf</FileName>
    <Width>415</Width>
    <Height>300</Height>
    <Top>130</Top>
    <Left>130</Left>
    <BackColor>Beige</BackColor>
  </Sticky>
</StickyList>



 b-4 プロパティを複数のフォームで(b-1 + b-3)
    



関連記事
スポンサーサイト

 【C#】Fakesticky

0 Comments

Leave a comment