これまではエクスプローラーの劣化版のようなリストビューをつかってファイル等にコメントをつけてきました。今回はルートフォルダから順番にたどっていくのではなくファイル等のパスとコメントを直接ダイアログに入力してコメントを設定することができるようにします。

上側のテキストボックスはFilePathTextBoxクラスを使用しています。ファイルやフォルダをドロップしたり、ファイル等をコピーしてペーストするとそのパスが入力されます。FilePathTextBoxクラスは以下のページで解説しています。
FilePathTextBoxのテキストが変更されるとFilePathTextBox.Textは有効なパスなのかどうかを調べます。そしてそのパスが存在する場合はForm1.FileTagsのなかに登録されているかどうかを調べます。登録されている場合はこのコメントをリッチテキストボックスに表示させます。パスではない文字列、パスではあっても登録されていない場合はなにも表示させません。
| 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 | public partial class Form3 : Form {     public Form3()     {         InitializeComponent();         filePathTextBox1.TextChanged += FilePathTextBox1_TextChanged;         buttonOK.Click += ButtonOK_Click;     }     private void FilePathTextBox1_TextChanged(object sender, EventArgs e)     {         string path = filePathTextBox1.Text;         if(File.Exists(path) || Directory.Exists(path))         {             Form1 f = (Form1)this.Owner;             FileTag tag = f.FileTags.FirstOrDefault(x => x.FilePath == path);             if(tag != null)             {                 richTextBox1.Text = tag.Text;                 return;             }         }         richTextBox1.Text = "";     } } | 
[登録]ボタンがクリックされるとFilePathTextBoxに入力されている文字列はファイル等のパスなのか調べます。そして有効なパスである場合はすでに登録されたデータがあるかどうかを調べます。
FilePathTextBoxに入力されている文字列はファイル等のパスではない場合はエラーメッセージを表示します。既に登録されているデータがある場合は上書きをします。登録されているデータがない場合は新しく登録します。
| 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 | public partial class Form3 : Form {     public string Path = "";     public string TagText = "";     private void ButtonOK_Click(object sender, EventArgs e)     {         string path = filePathTextBox1.Text;         if(File.Exists(path) || Directory.Exists(path))         {             Form1 f = (Form1)this.Owner;             FileTag tag = f.FileTags.FirstOrDefault(x => x.FilePath == path);             if(tag != null)             {                 tag.Text = richTextBox1.Text;             }             else             {                 FileTag newTag = new FileTag();                 newTag.FilePath = path;                 newTag.Text = richTextBox1.Text;                 f.FileTags.Add(newTag);             }             Path = path;             TagText = richTextBox1.Text;             this.Close();         }         else         {             MessageBox.Show("パスが正しく設定されていません!", "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error);         }     } } | 
[操作] ⇒ [パスを指定して登録]を選択すると上記のフォームが表示されます。Form1のリストビューで同じファイル等が選択されている場合はリッチテキストボックスに表示されているコメントを新たに登録されたものに変更します。

| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | public partial class Form1 : Form {     private void MenuItemFromPath_Click(object sender, EventArgs e)     {         SaveOldData();         Form3 f = new Form3();         f.ShowDialog(this);         if(SelectedPath == f.Path)         {             richTextBox1.Text = f.TagText;         }         f.Dispose();     } } | 
ところでリストビューにもコメントの項目があります。長すぎるコメントを表示することはできませんが、先頭の10~20文字程度(改行なし)であれば表示させることができそうです。
GetCommentFromPath(string path)メソッドはファイル等のパスからコメントを取得するためのものです。最大で30文字取得します。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | public partial class Form1 : Form {     string GetCommentFromPath(string path)     {         FileTag tag = FileTags.FirstOrDefault(x => x.FilePath == path);         if(tag != null)         {             string str = tag.Text;             str = str.Replace("\r\n", "");             str = str.Replace("\n", "");             if(str.Length < 30)                 return str;             else                 return str.Substring(0, 30);         }         else             return "";     } } | 
リストビューで選択されているファイル等が変更されたときもコメントの項目を変更しなければなりません。しかし本当に変更しなければならないのは新しく選択されたファイル等とそれまで選択されていたファイル等が同じフォルダにあるときだけです(異なる場合はリストビューの内容が完全に入れ替わってしまうため)。
| 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 | public partial class Form1 : Form {     string _selectedPath = "";     string _oldSelectedPath = "";     string SelectedPath     {         get         {             return _selectedPath;         }         set         {             // これまで選択されていたパスのコメントを記憶する             SaveOldData();             // 新しく追加されたメソッド             SetOldComentToListView(value);             // 選択されたパスのコメントを表示させる             LoadNewData(value);         }     }     void SetOldComentToListView(string value)     {         if(Directory.Exists(value) || File.Exists(value))         {             if(Directory.Exists(_oldSelectedPath) || File.Exists(_oldSelectedPath))             {                 FileInfo oldInfo = new FileInfo(_oldSelectedPath);                 FileInfo newInfo = new FileInfo(value);                 if(oldInfo.DirectoryName == newInfo.DirectoryName)                 {                     string name = oldInfo.Name;                     foreach(ListViewItem item in listView1.Items)                     {                         if(item.Text == name)                         {                             var subItem = item.SubItems;                             subItem[5].Text = GetCommentFromPath(_oldSelectedPath);                             return;                         }                     }                 }             }         }     } } | 
そして今回の処理によってファイル等のコメントが変更されたときも、コメントがつけられたファイルと同じフォルダを参照しているときはリストビューの項目を変更する必要があります。
| 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 | public partial class Form1 : Form {     private void MenuItemFromPath_Click(object sender, EventArgs e)     {         SaveOldData();         Form3 f = new Form3();         f.ShowDialog(this);         if(SelectedPath == f.Path)         {             richTextBox1.Text = f.TagText;         }         SetComentToListView(f.Path);         f.Dispose();     }     void SetComentToListView(string path)     {         if(Directory.Exists(path) || File.Exists(path))         {             {                 FileInfo newInfo = new FileInfo(path);                 if(CurFolderPath == newInfo.DirectoryName)                 {                     string name = newInfo.Name;                     foreach(ListViewItem item in listView1.Items)                     {                         if(item.Text == name)                         {                             var subItem = item.SubItems;                             subItem[5].Text = GetCommentFromPath(path);                             return;                         }                     }                 }             }         }     } } | 
