前節の仮想ListViewのサンプルに加えて
各行にCheckBoxを表示させます。
コツがあって
単純にListViewのCheckBoxesプロパティーをtrueとするだけでは見えません。
さらに
ListViewItemのCheckedプロパティーをtrue→falseなどと
あえて無駄に思えるかもしれない操作をしないと見えません。
さらにさらに
ここまででチェックボックスは見えるようになりますが
クリックしても反応しません orz
MouseClickイベントを定義して
自前で再描画してやる必要があります。
仮想ListViewは少し面倒ですが
速度的な恩恵が多いのでその辺は我慢で。
また、チェックボックスをダブルクリックすると
チェックのON/OFFがズレます。なんだろう?バグ?
これの回避策については次節で
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; namespace VirtualListViewSample { public partial class Form1 : Form { // ListViewItem数 const int _size = 1000; // RetrieveVirtualItemで返すもの ListViewItem[] _item = new ListViewItem[_size]; public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { // Column追加 listView1.Columns.Insert(0, "ファイル", 180, HorizontalAlignment.Left); listView1.Columns.Insert(1, "フォルダ", 180, HorizontalAlignment.Left); listView1.Columns.Insert(2, "サイズ", 80, HorizontalAlignment.Right); // 適当にItem追加 for(int index = 0; index < _size; index++) { _item[index] = new ListViewItem( new string[] { "sample_" + index.ToString() + ".txt", @"c:\sample", index.ToString(), } ); // ※一旦、Checkedプロパティーを設定→解除することで見えるようになります _item[index].Checked = true; _item[index].Checked = false; } // 表示を詳細に listView1.View = View.Details; // 1行全体選択 listView1.FullRowSelect = true; // チェックボックスを有効に listView1.CheckBoxes = true; // // ここから仮想ListView関連 // // 仮想モードON listView1.VirtualMode = true; // Item数設定 listView1.VirtualListSize = _size; // 必須:描画に必要なListViewItemを返すイベント追加 listView1.RetrieveVirtualItem += new RetrieveVirtualItemEventHandler(listView1_RetrieveVirtualItem); // チェックボックスをクリックされたら再描画するために必要 listView1.MouseClick += new MouseEventHandler(listView1_MouseClick); // ボタンハンドラ button1.Click += new EventHandler(button1_Click); } // チェックボックスがクリックされたらその部分を再描画 void listView1_MouseClick(object sender, MouseEventArgs e) { ListView listview = (ListView)sender; ListViewItem item = listview.GetItemAt(e.X, e.Y); if (item != null) { if (e.X < (item.Bounds.Left + 16)) { item.Checked = !item.Checked; listview.Invalidate(item.Bounds); } } } // // 引数が示すindexのアイテムを返すと描画される // void listView1_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e) { e.Item = _item[e.ItemIndex]; } // ボタンが押されたら選択中アイテムを表示 void button1_Click(object sender, EventArgs e) { if(listView1.SelectedIndices.Count > 0) { int index = listView1.SelectedIndices[0]; MessageBox.Show(_item[index].SubItems[0].Text); } } } }
コメントを残す