З часів появи колись культового Delphi сталося багато змін. Але, що залишилося - тормознутость деяких вбудованих візуальних елементів.
Мені довелося з цим зіткнутися при розробці простого Чеккер доменів. Дуже зручний, здавалося б, елемент інтерфейсу - стовпець з чекбоксів - на ділі моторошно гальмував. Щоб відзначити 500 рядків потрібно близько 10 секунд. 1000 записів збільшували час рази в 4 (а не в 2, як можна подумати). Ніякі хитрощі не давали істотного приросту продуктивності.
Погуглити інтернет, розпрощався з думкою щось зробити на основі даного типу стовпця.
Новачки скаржилися на повільну роботу, а «старички» радили використовувати звичайний чекбокс, доданий програмно в потрібне місце. Виходить, що потрібних місць багато, а маніпулювати відображенням чекбоксів все одно доведеться вручну - визначити видимі рядки, встановити чекбокс в потрібне місце, «згадати» відображення (вкл / викл) кожного. Почав уже підводити себе до такого хаку, але згадав про ще один з можливих типів стовпців - DataGridViewImageColumn.
Виявилося, це те, що потрібно. Способів «рулювання» багато, запропоную той, що використовував сам.
Для початку, треба підготувати 2 стану прапорця: відзначений і немає. У моєму випадку це була картинка, розміром 40 × 20 пікселів. При цьому, ширина колонки дорівнювала 20.
Застосувавши це зображення до осередку, вирівнюємо його по правому (або лівому) краю, в залежності від того, з якого боку «пташка».
Визначати стан вкл / викл можна, перевіривши краю, за якими вирівнюються картинки. Нехай таблиця зветься dataGridView1. Стовпець з «чекбоксами» (пам'ятаємо, що вони не справжні, а лише наша емуляція) буде найпершим. Вертикальне вирівнювання логічно робити по середи. Тоді перемикання чекбокса для першого рядка можна записати один з двох варіантів:
dataGridView1.Rows [0] .Cells [0] .Style.Alignment = DataGridViewContentAlignment.MiddleLeft;
// або
dataGridView1.Rows [0] .Cells [0] .Style.Alignment = DataGridViewContentAlignment.MiddleRight;
Так вирівнюємо зображення по лівому / правому (Left / Right) краю (вертикальне - по середині, на це вказує Middle).
Все супер. Тепер ми можемо програмно управляти відмітками в будь-якому рядку, створюючи ілюзію (яка залежить від якості малюнка) повноцінного елемента.
Але це лише частина завдання. Непогано б дати можливість користувачу самому змінювати стан прапорців, клікаючи в осередках першого стовпця. У цьому допоможе подія CellClick - просто клацніть двічі на відповідному полі на вкладці Properties → Events при активному елементі форми DataGridView.
private void dataGridView1_CellClick (object sender, DataGridViewCellEventArgs e)
// e.RowIndex - рядок
// e.ColumnIndex - стовпець
// System.Drawing.Bitmap
// якщо обрана перший рядок і стовпець (негативні значення - заголовки).
if (e.ColumnIndex == 0 e.RowIndex> = 0) // якщо вирівнювання по лівому краю.
if (dataGridView1.Rows [e.RowIndex] .Cells [0] .Style.Alignment == DataGridViewContentAlignment.MiddleLeft)
//. то перемкнемо на праве вирівнювання
dataGridView1.Rows [e.RowIndex] .Cells [0] .Style.Alignment = DataGridViewContentAlignment.MiddleRight;
>
else //. інакше - на ліве
dataGridView1.Rows [e.RowIndex] .Cells [0] .Style.Alignment = DataGridViewContentAlignment.MiddleLeft;
>
// заодно зняти виділення з рядка
dataGridView1.Rows [e.RowIndex] .Cells [0] .Selected = false;
>
>
Назва перехоплювача - dataGridView1_CellClick () - середовище розробки сформує автоматично. Ми ж додаємо відповідний код. Перерахування DataGridViewContentAlignment визначає константи для вирівнювання зображення в осередку.
В общем-то, це все. Для тих, хто дістався до сюди, покажу, як можна змінювати / комбінувати фонові картинки. Припустимо, Ви завантажили новий ресурс (зображення) і дали йому ім'я check. Доступ до впровадженим ресурсів здійснюється через Properties.Resources додатки. Якщо забули назву програми, можете подивитися його в вікні Solution Explorer. У моєму випадку, це MyWindowsApplication.
// для першого рядка використовувати ресурс check
dataGridView1.Rows [0] .Cells [0] .Value = MyWindowsApplication.Properties.Resources.check;
// для другої - check2
dataGridView1.Rows [1] .Cells [0] .Value = MyWindowsApplication.Properties.Resources.check2;
Дивно, але такий простий прийом прискорює роботу «по отмечіванію» на порядок (і навіть більше при збільшенні числа рядків).