前回は登録しているファイルにコメントをつける機能を追加しました。
前回の記事はこちら
今回はコメントのなかにある文字列を検索する機能を追加します。これならファイルを探すときに便利です。
まずは検索ボックスを表示させましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
public partial class FormSearch : Form { public string Word = ""; public FormSearch() { InitializeComponent(); buttonSearch.Click += ButtonSearch_Click; buttonSearch.DialogResult = DialogResult.OK; } private void ButtonSearch_Click(object sender, EventArgs e) { Word = textBox1.Text; } } |
あとは検索用のダイアログを表示させて検索結果を表示させるだけです。ダイアログの検索ボタンが押されたら、全TreeNodeのDataオブジェクトが集められ、コメント内に目的の文字列があるかどうかについて調べられます。条件を満たしたものがあれば、それをつかって別の新しいForm1クラスから生成されたダイアログが表示されます。
Form1クラスで生成されているのでメニューも使えます。ただ困ったこともあります。このダイアログからもコメントを編集することができてしまうことです。
それからコメントが反映されるのは別のTreeNodeが選択されるときです。そのため最後に選択されていたTreeNodeでコメントを編集しても反映されません。
この点については以下で対応できます。検索ダイアログが終了するときにどのTreeNodeが選択されているか調べて、それに対応するDataオブジェクトにコメントを保存すればよいのです。
1 2 3 4 5 6 7 8 9 10 11 |
public partial class Form1 : Form { void SaveThisComment() { if (treeView1.SelectedNode != null) { Data data = (Data)treeView1.SelectedNode.Tag; data.Comment = textBox1.Text; } } } |
もうひとつの問題は検索を開始するときに選択されているTreeNodeのコメントが編集されていた場合です。
このときはまずそれぞれのTreeView.SelectedNodeに対応するDataオブジェクトが同じかどうかを確認します。そして同じであれば以下のコードでいったんどこも選択されていない状態にして改めて選択すれば検索結果を表示していたダイアログでのコメントの変更も反映されます。
1 2 3 4 5 6 |
if (form1.treeView1.SelectedNode.Tag == treeView1.SelectedNode.Tag) { TreeNode node1 = treeView1.SelectedNode; treeView1.SelectedNode = null; treeView1.SelectedNode = node1; } |
以下は検索用のダイアログを表示して[検索]ボタンが押されたら結果を表示するメソッドです。CreateTreeFromDataメソッドはDataのリストからツリー構造を構築するためのメソッドです。
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 |
public partial class Form1 : Form { private void MenuItemSearch_Click(object sender, EventArgs e) { SaveThisComment(); FormSearch form = new FormSearch(); if (form.ShowDialog() == DialogResult.OK) { string word = form.Word; List<Data> datas = new List<Data>(); foreach (TreeNode node in treeView1.Nodes) { datas.Add((Data)node.Tag); } // コメントに検索ワードがあるDataオブジェクトを集める List<Data> datas1 = datas.Where(x => x.Comment.IndexOf(word) != -1).ToList(); // 新しいForm1ダイアログを生成して結果を表示させる Form1 form1 = new Form1(); form1.CreateTreeFromData(datas1); form1.ShowDialog(); // ダイアログが閉じられたあとの処理 form1.SaveThisComment(); if (form1.treeView1.SelectedNode != null && form1.treeView1.SelectedNode.Tag == treeView1.SelectedNode.Tag) { TreeNode node1 = treeView1.SelectedNode; treeView1.SelectedNode = null; treeView1.SelectedNode = node1; } } form.Dispose(); } void CreateTreeFromData(List<Data> datas) { treeView1.BeginUpdate(); treeView1.Nodes.Clear(); foreach (Data data in datas) { TreeNode node = new TreeNode(); node.Tag = data; node.Text = data.FilePath; node.Checked = data.IsChecked; treeView1.Nodes.Add(node); } treeView1.EndUpdate(); } } |
検索結果を別のファイルに保存したくなることもあるかもしれません。他にTreeNodeの横にあるチェックボックスにチェックがあるものだけを保存するメソッドもつくってみました。
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 |
public partial class Form1 : Form { private void MenuItemSaveFileCheckItem_Click(object sender, EventArgs e) { SaveFileCheckItem(); } void SaveFileCheckItem() { SaveFileDialog dialog = new SaveFileDialog(); dialog.Title = "チェックがされているアイテムだけファイルに保存する"; dialog.Filter = "データファイル|*.pvf2"; if (dialog.ShowDialog() == DialogResult.OK) { SaveFileCheckItem(dialog.FileName); } dialog.Dispose(); } void SaveFileCheckItem(string filePath) { List<Data> datas = new List<Data>(); foreach (TreeNode node in treeView1.Nodes) { Data data = (Data)node.Tag; if (data.IsChecked) datas.Add(data); } Doc doc = new Doc(); doc.Datas = datas; XmlSerializer xml = new XmlSerializer(typeof(Doc)); StreamWriter sw = new StreamWriter(filePath); xml.Serialize(sw, doc); sw.Close(); } } |