- •В ведение в ado.Net
- •Потребитель данных
- •Поставщики данных
- •Источник данных — xml-файл
- •Элементы управления на форме Меню
- •Как устроены планки меню, статуса и панелей инструментов
- •Планка инструментов (ToolStrip)
- •Навигатор связей
- •Контейнер, расщепляющий форму
- •Создание таблиц и внедрение их в DataSet
- •Пояснения
- •Запись и чтение данных
- •Отображение данных связанной таблицы
- •Добавляем ограничение
- •Вторая, подчиненная таблица
- •Автоматическая навигация по записям связанной таблицы
- •Элемент управления BindingNavigator
- •Реакции на события в DataTable
- •Канонизация имен студентов
- •Вычисляемые колонки DataTable (Expression-Based DataColumn Objects)
- •Поиск в таблице DataTable и в компоненте DataGridView
- •Коррекция пользовательского интерфейса
- •Результат поиска
- •Поиск в DataGridView
- •Отбор данных из DataTable и отображение их в ListView
- •Как легко вносятся ошибки
- •Образ таблицы DataView
- •Методы Find и FindRows класса DataView
- •Задание
- •Элемент управления, который позволяет управлять отображением колонок DataGridView
Коррекция пользовательского интерфейса
Проверка на наличие текста в окне выпадающего списка (what == "") важна, так как в ее отсутствии метод Select выдает странный результат (убедитесь в этом самостоятельно). Но эту проверкку можно убрать, если вовремя скорректировать пользовательский интерфейс. Если текст в окне comboFind не выбран (или не набран), то сама команда поиска должна быть недоступной (disabled). Покажем, как можно добиться такого поведения.
Первый вариант. Обычным образом создать обработчик события TextUpdate для списка comboFind и вызвать в нем вспомогптельный метод (назовем его UpdateFindPanel), который должен управлять доступностью кнопки btnFindList (свойство Enabled), а также видимостью панели поиска (свойство Panel1Collapsed элемента типа SplitContainer).
Второй вариант делает то же самое, но с помощью лямбда-выражения (это выглядит значительно изящнее).
comboFind.TextUpdate += (s, a) => UpdateFindPanel();
Добавьте эту строку кода в нужное место (вычислите момент жизни приложения, когда следует это сделать). Метод UpdateFindPanel должен установить свойства кнопок и панели, как было указано ранее.
void UpdateFindPanel()
{
bool enabled = // Логическое выражение: Текст comboFind (освобожденный от white space) не пуст.
btnFindNext.Enabled = btnFindList.Enabled = btnFindView.Enabled = enabled;
split.Panel1Collapsed = !enabled;
}
Добавьте обработчик события SelectedIndexChanged для выпадающего списка comboFind (в виде лямбда-выражения) и выполните в нем вызов метода UpdateFindPanel.
Теперь блок кода if (what == "") в методе Find можно убрать. Если добавить вызов UpdateFindPanel() в конструктор формы (или в обработчик события Load, то автоматически произойдет начальная установка свойства Enabled для всех кнопок.
Результат поиска
Напомним, что поиск производился в DataTable (в памяти), а его результат надо отобразить в DataGridView (на экране). Если поиск (вызов метода Select класса DataTable) был удачным, то показать результат можно путем маркировки в DataGridView той его ячейки, которая соответствует первой (rows[0]) строке из массива (rows) всех строк, найденных в DataTable. Это делается с помощью свойства CurrentCell компонента DataGridView. Заметим, что установка этого свойства провоцирует событие CellEnter — входа фокуса в ячейку DataGridView. Ячейка grid выделяется цветом, управляемым свойством SelectionBackColor класса DataGridViewCellStyle. Доступ к объекту DataGridViewCellStyle дает свойство DefaultCellStyle класса DataGridView.
Чтобы все прошло гладко, нам осталось вычислить целочисленный индекс той строки в DataGridView, которая соответствует первому элементу в массиве строк, найденных в DataTable. Простое действие — определение индекса, казалось бы не должно вызвать затруднений. Но именно оно вынуждает напряженно искать решение.
Дело в том, что результатом отбора (метода Select) является массив ссылок на объекты класса DataRow, содержащиеся во внутренней коллекции объекта DataTable. Порядок элементов в этом массиве никак не связан с порядком отображения строк таблицы в DataGridView.
Вы заметили, что отображаемые строки можно сортировать самыми разными способами, если последовательно нажимать мышью заголовки всех столбцов элемента DataGridView? Эта внешняя сортировка никак не влияет на то значение, которое дает выражение rows[0][0]. Оно всего лишь выбирает значение, расположенное в нулевом столбце той строки DataTable, индекс которой записан в элементе rows[0]. Нулевой столбец соответствует полю ID и мы узнаем ключ первой из найденных записей. Если строки DataGridView в данный момент отсортированы по этому столбцу, то результат поиска будет показан (маркирован) правильно, если по другому — нет.
В процессе отбора строк из DataTable не учитывается факт внешней сортировки, так как эта структура расположена в памяти и не сортируется при нажатии на заголовки DataGridView. Напомним, что компонент DataGridView лишь отображает объекты.
