Введение в ADO.NET. Источник данных - XML-файл. Отображение данных связанной таблицы, страница 12

Проверка на наличие текста в окне выпадающего списка (what == "") важна, так как в ее отсутствии метод Select выдает странный результат (убедитесь в этом самостоятельно). Но эту проверкку можно убрать, если вовремя скорректировать пользовательский интерфейс. Если в окне comboFind текст не выбран (или не набран), то сама команда поиска должна быть недоступной (disabled). Каждое изменение содержимого этого окна должно стирать надпись «NotFound». Покажем, как можно добиться такого поведения.

¨  В режиме дизайна поставьте фокус в окно comboFind, нажмите кнопку Events и дважды щелкните на событии TextUpdate, затем на событии KeyDown, и, наконец на событии SelectedIndexChanged,

¨  В функции обработки этих событий введите следующий код.

  void comboFind_TextUpdate(object sender, EventArgs e)

  {

    btnFindNext.Enabled = // Здесь ваш код

  }

  void comboFind_KeyDown(object sender, KeyEventArgs e)

  {

    sNotFound.Visible = false;

    if (e.KeyCode == Keys.Enter)

      Find();

  }

  void comboFind_SelectedIndexChanged(object sender, EventArgs e)

  {

    btnFindNext.Enabled = // Здесь ваш код

    // Здесь ваш код

  }

Теперь блок кода if (what == "") в методе Find можно убрать. Начальную установку свойства Enabled для кнопки btnFindNext можно произвести тремя способами:

¨  В конструктор формы (после вызова InitializeComponent();) добавить код:

    btnFindNext.Enabled = // Здесь ваш код

¨  Для главной формы ввести обработчик события Load и вставить него вызов метода SelectedIndexChanged. Такая имитация события "Выбор строки списка" допустима потому, что мы можем задать синтаксически и семантически правильные аргументы для функции обработки. Вот они:

    comboFind_SelectedIndexChanged (comboFind, EventArgs.Empty);

В приложениях Win32 аналогом этого действия является вызов функции API SendMessage с кодом сообщения CBN_SELCHANGE. С осторожностью пользуйтесь описанным приемом. Убедитесь, что задаваемые вами параметры имеют смысл.

¨  В метод MainForm_Load, или в конструктор вставить код, провоцирующий событие SelectedIndexChanged.

    comboFind.SelectedIndex = 0;

    comboFind.SelectedIndex = -1;

В нашем случае этот прием не проходит, так как в начальный момент список пуст и обращение к нулевому элементу вызовет исключение. Если оставить только одну, последнюю строку кода, то прием не сработает потому, что индекс равен –1 по умолчанию (изменения нет — событие не происходит). Если заполнить список внутри InitializeComponent, то прием сработает.

Предпочитаю второй вариант потому, что не хочется повторять код установки свойства Enabled, и учитывая то, что подобных, обездвиженных кнопок будет несколько.

Результат поиска

Напомним, что поиск производился в DataTable (в памяти), а его результат надо отобразить в DataGridView (на экране). Если поиск (вызов метода Select класса DataTable) был удачным, то показать результат можно путем маркировки в DataGridView той его ячейки, которая соответствует первой (rows[0]) строке из массива (rows) всех строк, найденных в DataTable.

Это делается с помощью свойства CurrentCell компонента DataGridView. Оно дает доступ к ячейке с помощью индексаторов коллекций Rows и Cells. Заметим, что установка этого свойства провоцирует событие CellEnter — входа фокуса в ячейку DataGridView, которое нам скоро понадобится. Строка выделяется цветом, управляемым свойством SelectionBackColor класса DataGridViewCellStyle. Доступ к объекту DataGridViewCellStyle дает свойство DefaultCellStyle класса DataGridView.

Чтобы все прошло гладко, нам осталось вычислить целочисленный индекс той строки в DataGridView, которая соответствует первому элементу в массиве строк, найденных в DataTable. Простое действие — определение индекса, казалось бы не должно вызвать затруднений. Но именно оно вынуждает напряженно искать решение.

Дело в том, что результатом отбора (метода Select) является массив ссылок на объекты класса DataRow, содержащиеся во внутренней коллекции объекта DataTable. Порядок элементов в этом массиве никак не связан с порядком отображения строк таблицы в DataGridView.