エクスプローラの「フォルダオプション」では「ポイントして選択し、シングルクリックで開く」という設定があります。これと同じことをListViewで行えるようにしてみましょう。
ポイントで選択できるようにするには、ListViewのHoverSelectionプロパティをTrueにします。また、シングルクリックで開くという動作を実現するためには、ActivationプロパティをItemActivation.OneClickとし、「開く」という処理をItemActivateイベントハンドラで行うようにします。
次の例では、リストビューコントロールListView1のアイテムがポイントで選択でき、シングルクリックによりそのアイテムの名前が表示されるようにしています。
'フォームのLoadイベントハンドラ Private Sub Form1_Load(ByVal sender As Object, _ ByVal e As EventArgs) _ Handles MyBase.Load 'ポイントで選択できるようにする ListView1.HoverSelection = True 'シングルクリックでアクティブにできるようにする ListView1.Activation = ItemActivation.OneClick End Sub 'アイテムがアクティブになった時 Private Sub ListView1_ItemActivate(ByVal sender As Object, _ ByVal e As EventArgs) _ Handles ListView1.ItemActivate Dim lv As ListView = DirectCast(sender, ListView) 'フォーカスのあるアイテムのTextを表示する MessageBox.Show(lv.FocusedItem.Text) End Sub
//フォームのLoadイベントハンドラ private void Form1_Load(object sender, System.EventArgs e) { //ポイントで選択できるようにする ListView1.HoverSelection = true; //シングルクリックでアクティブにできるようにする ListView1.Activation = ItemActivation.OneClick; //ItemActivateイベントハンドラの追加 ListView1.ItemActivate += new EventHandler(ListView1_ItemActivate); } //アイテムがアクティブになった時 private void ListView1_ItemActivate(object sender, EventArgs e) { ListView lv = (ListView) sender; //フォーカスのあるアイテムのTextを表示する MessageBox.Show(lv.FocusedItem.Text); }
エクスプローラにはさらに「ブラウザのように、アイコンタイトルに下線を付ける」というオプションがありますが、これと同じようなことをできないものでしょうか?これは、MouseMoveイベントでポイントされているアイテムを調べ、そのアイテムのフォントを下線付きにすれば何とかなりそうです。次にそのMouseMoveイベントハンドラでのコード例を示します。
'前回ポイントしたListViewItem Private pointedListViewItem As ListViewItem = Nothing 'MouseMoveイベントハンドラ Private Sub ListView1_MouseMove(ByVal sender As Object, _ ByVal e As MouseEventArgs) _ Handles ListView1.MouseMove Dim lv As ListView = DirectCast(sender, ListView) 'ポイントしているListViewItemを取得 Dim lvi As ListViewItem = lv.GetItemAt(e.X, e.Y) If Not pointedListViewItem Is lvi Then 'ポイントされているアイテムに下線を付ける If Not lvi Is Nothing AndAlso Not lvi.Font.Underline Then Dim old As Font = lvi.Font 'サブアイテムのフォントは変更しない If lvi.UseItemStyleForSubItems Then lvi.UseItemStyleForSubItems = False End If 'フォントスタイルにUnderlineを追加する Dim fs As FontStyle = old.Style Or FontStyle.Underline Dim fnt As New Font(old.FontFamily, old.Size, fs) lvi.Font = fnt End If '前回ポイントされていたアイテムの下線を取る If Not pointedListViewItem Is Nothing AndAlso _ pointedListViewItem.Font.Underline Then Dim old As Font = pointedListViewItem.Font 'フォントスタイルのUnderlineを削除する Dim fs As FontStyle = old.Style Xor FontStyle.Underline Dim fnt As New Font(old.FontFamily, old.Size, fs) pointedListViewItem.Font = fnt End If 'ポイントされているアイテムを記憶する pointedListViewItem = lvi End If End Sub
//前回ポイントしたListViewItem private ListViewItem pointedListViewItem = null; //MouseMoveイベントハンドラ private void ListView1_MouseMove(object sender, MouseEventArgs e) { ListView lv = (ListView) sender; //ポイントしているListViewItemを取得 ListViewItem lvi = lv.GetItemAt(e.X, e.Y); if (pointedListViewItem != lvi) { //ポイントされているアイテムに下線を付ける if (lvi != null && !lvi.Font.Underline) { Font old = lvi.Font; //サブアイテムのフォントは変更しない if (lvi.UseItemStyleForSubItems) lvi.UseItemStyleForSubItems = false; //フォントスタイルにUnderlineを追加する FontStyle fs = old.Style | FontStyle.Underline; Font fnt = new Font(old.FontFamily, old.Size, fs); lvi.Font = fnt; } //前回ポイントされていたアイテムの下線を取る if (pointedListViewItem != null && pointedListViewItem.Font.Underline) { Font old = pointedListViewItem.Font; //フォントスタイルのUnderlineを削除する FontStyle fs = old.Style ^ FontStyle.Underline; Font fnt = new Font(old.FontFamily, old.Size, fs); pointedListViewItem.Font = fnt; } //ポイントされているアイテムを記憶する pointedListViewItem = lvi; } }
上記のコードを試してみると、かなりちらつきます。ちらつきを抑える方法は、「The Code Project - Flicker-free ListView in .NET - Part 2」等で紹介されています。