前回はノードを追加する操作を追加しました。今回はデータをファイルとして保存する機能を追加します。
SyncTreeViewではTreeNodeExのリストを取得するメソッドとしてGetTreeNodeExsを作成しました。
ということでこれを使えば簡単にできそうです。
ファイルとして保存する
まずこんなクラスをつくります。
1 2 3 4 |
public class Doc { public List<TreeNodeEx> treeNodeExes = null; } |
これでは例外が発生します。
1 2 3 4 5 6 7 8 9 |
XmlSerializer xml = new XmlSerializer(typeof(Doc)); SaveFileDialog save = new SaveFileDialog(); if (save.ShowDialog() == DialogResult.OK) { StreamWriter sw = new StreamWriter(save.FileName); xml.Serialize(sw, doc); sw.Close(); } |
Dataをシリアル化できるようにする必要があります。そこでコンストラクタ内で
1 2 3 4 5 6 7 8 9 10 11 |
public partial class Form1 : Form { public Form1() { InitializeComponent(); types = new List<Type>(); types.Add(typeof(Data)); } List<Type> types = null; } |
そしてXmlSerializerのコンストラクタの第二引数にtypes.ToArray()を渡すと例外は発生しません。
おっと、そのまえにRichDataにデータを保存する必要があります。
1 2 3 4 5 6 7 8 9 10 |
public partial class Form1 : Form { public void SaveToMoromy() { if(syncRichTextBoxEx1.Modified) syncRichTextBoxEx1.SaveToMemory(); if (syncRichTextBoxEx2.Modified) syncRichTextBoxEx2.SaveToMemory(); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
public partial class Form1 : Form { private void saveAsFileToolStripMenuItem_Click(object sender, EventArgs e) { SaveToMoromy(); Doc doc = new Doc(); doc.treeNodeExes = syncTreeViewEx1.GetTreeNodeExs(null); XmlSerializer xml = new XmlSerializer(typeof(Doc), types.ToArray()); SaveFileDialog save = new SaveFileDialog(); if (save.ShowDialog() == DialogResult.OK) { StreamWriter sw = new StreamWriter(save.FileName); xml.Serialize(sw, doc); sw.Close(); } } } |
ファイルを読み出すときは読み出したデータからノードを再構築する必要があります。これもSyncTreeView.RestoreNodesメソッドを使えば実現することができます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
public partial class Form1 : Form { private void openFileToolStripMenuItem_Click(object sender, EventArgs e) { OpenFileDialog open = new OpenFileDialog(); if (open.ShowDialog() == DialogResult.OK) { StreamReader sr = new StreamReader(open.FileName); XmlSerializer xml = new XmlSerializer(typeof(Doc), types.ToArray()); var doc = (Doc)xml.Deserialize(sr); sr.Close(); syncTreeViewEx1.RestoreNodes(doc.treeNodeExes, null); } } } |
さてノードの開閉状態も保存できるようにしましょう。実は保存はされています。反映されていないだけです。
こうすればファイルが読み込まれたときに開閉状態も復元されます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
public partial class Form1 : Form { private void openFileToolStripMenuItem_Click(object sender, EventArgs e) { OpenFile(); } void OpenFile() { OpenFileDialog open = new OpenFileDialog(); open.Filter = "trtファイル|*.trt"; if (open.ShowDialog() == DialogResult.OK) { OpenFile(open.FileName); } } void OpenFile(string filePath) { StreamReader sr = new StreamReader(filePath); XmlSerializer xml = new XmlSerializer(typeof(Doc), types.ToArray()); var doc = (Doc)xml.Deserialize(sr); sr.Close(); syncTreeViewEx1.RestoreNodes(doc.treeNodeExes, null, InsertTo.LastChild); // ↓ これを追加 syncTreeViewEx1.SetExpands(null, doc.treeNodeExes.Select(x => x.IsExpanded).ToList()); } } |
SyncTreeViewでは以下のような処理がおこなわれます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
public partial class SyncTreeView : UserControl { public void SetExpands(TreeNodeEx targetNodeEx, List<bool> isExpands) { List<TreeNode> nodes = treeViewEx1.GetTreeNodes(targetNodeEx); int count = nodes.Count; if(nodes.Count > isExpands.Count) count = isExpands.Count; for (int i = 0; i < count; i++) { if(isExpands[i]) nodes[i].Expand(); else nodes[i].Collapse(); } } } |
あとCtrl+Sを押すと上書き保存できるようにしてみましょう。
ファイルが正常に保存されたり開かれた場合、そのファイルのパスを保存しておきます(フィールド変数 curFilePath)。「保存」メニューにショートカットキーを設定しておけば、Ctrl+Sが押されたときにsaveFileToolStripMenuItem_Clickが呼ばれます。フィールド変数 curFilePathに有効なファイルパスが格納されていない場合は保存ダイアログが表示されます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
public partial class Form1 : Form { string curFilePath = ""; private void saveAsFileToolStripMenuItem_Click(object sender, EventArgs e) { SaveAsFile(); } void SaveAsFile() { if (syncTreeViewEx1.IsEmpty) return; SaveToMoromy(); Doc doc = new Doc(); doc.treeNodeExes = syncTreeViewEx1.GetTreeNodeExs(null); XmlSerializer xml = new XmlSerializer(typeof(Doc), types.ToArray()); SaveFileDialog save = new SaveFileDialog(); save.Filter = "trtファイル|*.trt"; if (save.ShowDialog() == DialogResult.OK) { StreamWriter sw = new StreamWriter(save.FileName); xml.Serialize(sw, doc); sw.Close(); curFilePath = save.FileName; } } private void saveFileToolStripMenuItem_Click(object sender, EventArgs e) { SaveFile(); } void SaveFile() { if (syncTreeViewEx1.IsEmpty) return; if (!File.Exists(curFilePath)) { SaveAsFile(); return; } SaveToMoromy(); Doc doc = new Doc(); doc.treeNodeExes = syncTreeViewEx1.GetTreeNodeExs(null); XmlSerializer xml = new XmlSerializer(typeof(Doc), types.ToArray()); StreamWriter sw = new StreamWriter(curFilePath); xml.Serialize(sw, doc); sw.Close(); MessageBox.Show("ファイルを保存しました。\n" + curFilePath); } } |
これでCtrl+Sを押すと上書き保存ができるようになります。