DataGridView в паре с DataTable

Приложение взаимодействия элемента визуального отображения таблиц DataGridView и связанного источника данных типа DataTable. Приложение позволяет работать с выбранной таблицей SQL базы данных, осуществлять создание и удаление строк, редактирование ячеек с записью в базу данных.
Термин связанный источник подразумевает, что изменения значений ячеек, добавление и удаление строк элемента DataGridView синхронно передаётся объекту DataTable. И наоборот, изменения в связанном DataTable тут же отображаются в таблице DataGridView.
- — dgvDatabase для отображения списка таблиц базы данных;
- — dgvTable для редактирования выбранной таблицы базы.
База данных в составе приложения
Исследуемая база данных содержит 3 различных таблицы. Для расширенного эксперимента в таблицах создано многообразие типов данных: int, float, bit, nvarchar, date. Столбцы имеют различные свойства инициализации: NULL, NOT NULL и значения по умолчанию.
Файл базы данных прикреплен к исходнику приложения. Подключение базы данных к SQL серверу можно осуществить с помощью среды программирования Visual Studio, как подключиться подробно описано на странице создание, подключение и отсоединение баз данных в Visual Studio. Подключить базу так же можно и в среде администрирования баз данных SQL Server Management Studio.
Инициализация приложения
Инициализация приложения и интерфейс обращения к базе данных практически аналогичен описанному в статье DataGridView — просмотр баз данных LocalDB. Во время инициализации приложения происходит получение списка таблиц базы с помощью представления информационной схемы INFORMATION_SCHEMA.TABLES . После запроса метаданные возвращаются в виде строк для каждой отдельной таблицы базы и отображаются в элементе dgvDatabase.
В списке таблиц ключевым является столбец с названием TABLE_NAME . При выборе пользователем любой ячейки элемента dgvDatabase считывается название таблицы из строки и данные загружаются в элемент DataGridView dgvTable для последующего редактирования. Программный код инициализации заключен в оболочку метода Init(), который вызывается в конструкторе формы.
Создание новой строки
У элемента DataGridView внизу таблицы отображается строка, помеченная слева звездочкой. Это строка для добавления новых записей. Когда пользователь щелкает на эту строку, в элемент управления добавляется новая строка DataGridView со значениями по умолчанию. Когда пользователь нажимает клавишу ESC, новая строка исчезает. Это встроенная в функционал DataGridView WYSIWYG визуализация создания новой строки. Но для того, чтобы строка реально записалась в базу данных, необходим дополнительный программный код.
В прикрепленном приложении новая строка вставляется в базу данных после редактирования любой ячейки и перевода фокуса на другие строки. При редактировании ячейки новая строка появляется в связанном источнике данных, в нашем случае в объекте DataTable. В событии DataGridView.RowValidated, возникающем при потере фокуса можно отследить создание новой строки посредством свойства DataRowState.Added связанного источника. Если проверка истинна, то значения строки записываются в базу данных. Для валидации заполнения новой строки предназначено событие DataGridView.RowValidating.
Вставка значений новой строки в событии DataGridView.RowValidated, возникающим после окончания валидации:
Получение значений по умолчанию
При создании новой строки требуются значения по умолчанию, и очень желательна их идентичность значениям в базе данных. Хотя DataColumn в составе DataTable имеет свойство DataColumn.DefaultValue, оно не заполняется при SQL запросах. Запросить из базы данных реальные значения по умолчанию столбцов не получится. Это связано с тем, что значения по умолчанию могут содержать не только величины, но и инициализирующие функции, например: GetDate(), NEW_ID(), которые определяют значения столбцов непосредственно во время вставки строки. Если запросить значения по умолчанию с помощью схемы INFORMATION_SCHEMA.COLUMNS , то результат вернется в виде строк вида «getdate()» , «new_id()» , «((0))» , («2022-01-20») и так далее.
Но получить значения столбцов по умолчанию все же можно. Необходимую процедуру можно осуществить различными способами:
— создать полную пустую временную копию таблицы, вставить в нее строку, считать значения, удалить таблицу.
— вставка строки в текущую таблицу во время транзакции, после считывания значений, откат транзакции.
Каждый из способов имеет свои достоинства и недоставки, но оба они позволяют получать реальные значения по умолчанию для столбцов с помощью самого механизма базы данных.
Для описываемого приложения написан метод GetDefaultValues(. ) получения значений по умолчанию путем фиктивной вставки строки. Полученные default значения присваиваются соответствующим столбцам связанного источника данных DataTable. Ввод данных по умолчанию непосредственно в связанный источник освобождает от необходимости повторяющейся обработки события DefaultValuesNeeded.
- Запрос схемы столбцов текущей таблицы и получение свойств столбцов парно COLUMN_NAME-COLUMN_DEFAULT , исключая столбец первичного идентификатора;
- Фиктивная вставка строки в базу с пустыми значениями (не являющимися NULL) столбцов, исключая столбцы, у которых обнаружено значение по умолчанию;
- Полученные default значения последней вставленной строки присваиваются одноименным столбцам связанного источника.
После вышеописанной процедуры, при вставке новой строки в DataGridView, в соответствующих столбцах появляются значения по умолчанию идентичные предусмотренным в базе данных.
К сведению. Откат транзакции не возвращает назад значение IDENTITY (AUTO_INCREMENT) первичного ключа. Это прерогатива исключительно движка базы данных.
Программный код получения значений по умолчанию из базы данных:
Редактирование ячеек DataGridView
В загруженных строках dgvTable можно редактировать любую ячейку, кроме идентификатора. В приложении отслеживаются только изменения значений ячеек, далее отредактированное значение записывается в базу данных при потере фокуса ячейкой или после нажатия клавиши Enter.
Изменение значений своих ячеек элемент DataGridView сопровождает событием CellValueChanged. Редактируются ячейки, только существующие в базе, новые ячейки добавляются в базу данных во время вставки новой строки.
Валидация вводимых значений
Движок DataGridView имеет встроенную функциональность проверки соответствия типа вводимого значения типу ячейки. При связанном источнике данных ячейки наследуют типы соответствующих столбцов DataTable.
Валидация введенного в ячейку значения происходит в событии DataGridView.CellValidating при потере фокуса ячейкой. В данном событии может находиться программный код оповещения пользователя о недопустимости ввода текущего значения. Если проигнорировать некорректность в этом событии, возникнет событие DataGridView.DataError, которое вернет первоначальное корректное значение.
Сочетание этих двух событий с диалоговыми окнами позволяют создать визуальную логику исправления ошибочного ввода. После успешной валидации значение ячейки можно записать в SQL базу данных.
Программный алгоритм валидации вводимых значений с диалоговым оповещением пользователя:
Определение типа вводимого значения
Вводимое в ячейку значение отслеживается в событии CellValidating(object sender, DataGridViewCellValidatingEventArgs e) , где свойство e.FormattedValue содержит введенное пользователем значение. e.FormattedValue имеет тип object и поэтому неизвестен конкретный тип введенного значения. Например, e.FormattedValue содержит 5544 и нет сведений строка это или число. Проверка заключается в попытке конвертировать значение пользователя в тип, который должен содержать столбец.
Тип значения ячейки получаем из свойств столбцов связанного источника данных DataTable. Проверку соответствия типа производит метод приложения TryConvert(. ) . При успешной конвертации метод возвращает true, в противном случае false.
Программный код попытки конвертирования в заказанный тип. Применение метода показано в валидация вводимых значений.
Удаление строк
В приложении можно удалять одну и более выделенных строк элемента dgvTable. Для процедуры удаления используется событие DataGridView.KeyDown с отслеживанием нажатия клавиши DELETE. Используя идентификаторы строк, осуществляется SQL запрос удаления выбранных записей.
Перед удалением открывается диалоговое окно, где запрашивается подтверждение либо отмена пользователем данного действия.
Метод вставки новой строки в базу данных
При визуальной вставке новой строки в элемент DataGridView автоматически создается новая строка в связанном источнике DataTable, но реально в базу данных ничего не записывается. Для вставки новой строки непосредственно в базу данных требуется дополнительный программный код.
В приложении за запись новых строк отвечает метод главной формы Insert(DataTable dtSource, DataRow row) , который в качестве параметра получает новую строку. Данные новой строки записываются в SQL базу данных.
Программный код метода вставки строки в базу и синхронизации идентификаторов:
Синхронизация первичных ключей базы данных и DataGridView
В случае с автоматическим приращением (IDENTITY (AUTO_INCREMENT)), при вставке новых строк не обеспечивается идентичность первичных идентификаторов записей базы данных и строк элемента управления DataGridView, что может вызвать нежелательные последствия.
При создании новой строки, в событии dgvTable.RowEnter, ячейке идентификатора элемента dgvTable временно присваивается значение -1. Метод Insert(DataTable dtSource, DataRow row) написан так, что одновременно со вставкой строки запрашивается последний вставленный идентификатор. Далее данный идентификатор присваивается ячейке идентификатора новой строки связанного источника, таким образом обеспечивается идентичность первичных ключей.
Программный код выделения новой строки отличающимся цветом и временным идентификатором: Программный код синхронизации первичных ключей, полный код метода вставка новой строки:
Вместо заключения
В данной статье описана работа в паре элемента DataGridView и объекта DataTable в качестве источника данных. Практический пример прикреплен к странице. DataTable предоставляет простой и удобный интерфейс для работы с таблицами баз данных.
Функциональность DataTable в паре с элементом управления DataGridView можно применять для редактирования таблиц источников данных. Простота работы с классом DataTable позволяет писать приложения обработки данных в кратчайшие сроки.