4.4.2. Объект DataRowСодержимое объекта DataSet представляет собой набор записей, который представлен объектами DataRow. В запущенном приложении содержимое объекта DataSet доступно для изменений, например, если данные выводятся в элемент управления DataGridView, то, перемещаясь по отдельным клеткам, можно править значения как в обычной электронной таблице. При этом происходит изменение объекта DataRow, соответствующее заданной записи. Рассмотрим программное создание и изменение записей.
Программное создание и изменение записей таблицы данных
Создадим новое Windows-приложение. В конструкторе формы создаем экземпляр dtTours и поля, соответствующие таблице «Туры»: public Form1() Для того чтобы привязать созданные данные к элементу управления DataGridView, понадобилось создать экземпляр myDataView класса DataView. Каждый объект DataTable содержит объект DataView, причем этот объект, используемый по умолчанию, называется DataTable.DefaultView. Данный объект неоднократно использовался ранее, например, в предыдущем проекте для вывода данных: dataGrid1.DataSource = dsTours.Tables["Туры"].DefaultView; Один объект DataTable может иметь несколько объектов DataView - это удобно для вывода одних и тех же данных, отфильтрованных или отсортированных различным образом. Запускаем приложение. На экранной форме представлена готовая структура таблицы «Туры» (рис. 110). Рис. 110. Структура таблицы «Туры» В данном проекте не будем подключаться к какой-либо базе данных - попробуем заполнить таблицу записями программно. Для добавлений одной новой записи перед созданием экземпляра myDataView вставляем следующий фрагмент кода: DataRow myRow = dtTours.NewRow(); Запускаем приложение (рис. 111). В таблице появилась первая запись. Рис. 111. Добавление записи в таблицу Добавим еще одну запись: DataRow myRow2 = dtTours.NewRow(); Название, указываемое в квадратных скобках объектов myRow или myRow2, представляет собой имя столбца, которое мы определили в самом начале. К столбцу можно обращаться и по индексу. Для демонстрации создадим следующий код: DataRow myRow = dtTours.NewRow(); Нумерация столбцов начинается с нуля. Более удобный способ добавления записей - применение свойства ItemArray объекта DataRow, где можно задавать значения полей в виде массива: DataRow myRow3 = dtTours.NewRow(); Здесь мы указали значение поля «Информация», равное null, - таким образом можно пропускать неизвестные поля (рис. 112). Рис. 112. Вставка записи с одним значением null Конечно, вставка записей вручную в объект DataSet, не связанный с хранилищем данных, имеет не очень большой смысл. Поэтому рассмотрим, как вставлять (и изменять) данные в уже загруженный кэш данных. Изменим текущий проект. В коде проекта после отображения данных в элементе DataGrid: dataGrid1.DataSource = dsTours.Tables["Туры"].DefaultView; будем добавлять соответствующие строки. Для изменения, например, пятой строки, мы указываем в свойстве Rows объекта dtTours ее индекс, равный числу 4, так как нумерация полей в строке начинается с нуля, затем вызываем метод BeginEdit для начала редактирования, устанавливаем группу свойств и в заключение принимаем изменения, вызывая метод EndEdit: DataRow myRow=dtTours.Rows[4]; myRow.BeginEdit(); Тот же самый результат мы получим с помощью свойства ItemArray: DataRow myRow=dtTours.Rows[4]; Здесь мы установили для третьего и четвертого полей, которые являются вычисляемыми, значения null, подразумевая, что они останутся по умолчанию, а при запуске заполнятся своими значениями (рис. 113). Рис. 113. Пропущенные вычисляемые поля заполняются своими значениями Для удаления заданной записи нужно создать объект DataRow, которому передается индекс строки, а затем вызвать метод Remove свойства Rows объекта DataTable: DataRow myRow2 = dtTours.Rows[0]; Этого достаточно для удаления строки, но для того, чтобы пометить заданную строку как удаленную, вызываем метод Delete: myRow2.Delete(); В результате у нас удалится строка (рис. 114), причем объект DataTable пометит ее в качестве удаленной - это необходимо, чтобы избежать ошибок (например, в связанных записях). Рис. 114. Первая строка, имеющая индекс 0, была удалена
Свойство RowState
При работе с данными приходится постоянно вносить изменения в записи - добавлять, редактировать или удалять. Объект DataRow обладает свойством RowState, позволяющим отслеживать текущий статус строки. Создадим новое приложение. В конструкторе формы мы создадим всего одно поле, затем одну запись, статус которой будем отслеживать: public Form1() { Запускаем приложение. В текстовое поле выводится статус записи myRow (рис. 115). Значение Detached означает, что запись не относится к объекту DataTable. После добавления ее статус изменяется на Added - теперь она существует в объекте DataTable, но ее нет в базе данных. Конечно, здесь не рассматривается взаимодействие с источником записей, но это же значение будет у записей, добавляемых в DataGrid после вывода данных из базы при наличии подключения. Вызывая метод AcceptChanges объекта DataTable, выполняется прием всех изменений, поэтому статус DataRow изменяется на Unchanged - теперь запись считается «своей», она не была изменена после вызова метода. После вызова метода Delete запись помечается удаленной - она еще не полностью удалена, в случае отмены изменений статус будет восстановлен. Действительно, вызов метода RejectChanges объекта DataTable восстанавливает запись до состояния Unchanged. Рис. 115. Приложение RowState Свойство RowState всегда возвращает отдельное, доступное только для чтения значение. Это свойство используется для поиска записей, соответствующих заданному статусу, а также при передаче изменений в базу данных.
Свойство RowVersion
Свойство RowVersion предназначено для извлечения значения записи (объекта DataRow), зависящего от совершенных изменений. Возможны следующие версии записи: - Current - текущее значение - Default - значение по умолчанию - Original - первоначальное значение - Proposed - предполагаемое значение Создадим новое приложение. В классе формы объявим объекты DataRow и DataTable: DataRow myRow; DataTable dtTours; В конструкторе формы создаем запись, определяем источник данных для элемента DataGridView, а также отключаем его доступность: public Form1() { Создадим метод TestRowVersion, в котором будет проверяться свойство RowVersion записи: private void TestRowVersion() { Метод HasVersion позволяет определить, поддерживает ли объект myRow версию данных, указываемую в скобках. В случае подтверждения будет выполняться код оператора - выводится в элемент rtbReport соответствующее сообщение. В обработчике кнопки btnBeginEdit (Редактировать) вызываем метод BeginEdit, устанавливаем новое значение записи: private void btnBeginEdit_Click(object sender, System.EventArgs e) { В обработчике кнопки btnEndEdit завершаем редактирование записи: private void btnEndEdit_Click(object sender, System.EventArgs e) { В обработчике кнопки btnCancelEdit отказываемся от внесенных изменений: private void btnCancelEdit_Click(object sender, System.EventArgs e) { В обработчике кнопки btnDelete удаляем объект myRow: private void btnDelete_Click(object sender, System.EventArgs e) { В обработчике кнопки «Очистить отчет» просто удаляем содержимое текстового поля: private void btnClear_Click(object sender, EventArgs e) { Запускаем приложение. После нажатия кнопки «Begin Edit» мы начинаем редактирование записи, вводится новое значение - «Франция». Оно становится значением по умолчанию (Default) и предполагаемым Proposed, значение «Таиланд» является текущим (Current) (рис. 116). Рис. 116. Демонстрация работы. Шаг 1 - Редактирование Отменяем редактирование, нажимая кнопку «Cancel Edit». При этом значение «Таиланд» становится текущим (Current) и по умолчанию (Default) (рис. 117). Рис. 117. Демонстрация работы. Шаг 2 - Отмена редактирования Снова начинаем редактирование - картина повторяется (рис. 118). Рис. 118. Демонстрация работы. Шаг 3 - Повторное редактирование На этот раз завершаем редактирование, нажимая кнопку «End Edit» - новое значение «Франция» становится текущим (Current) и по умолчанию (Default) (рис. 119). Рис. 119. Демонстрация работы. Шаг 4 - Завершение редактирования Теперь нажимаем кнопку «Удалить» - при этом удаляется сам объект myRow и дальнейшее изменение его значений оказывается невозможным (рис. 120). Рис. 120. Демонстрация работы. Шаг 5 - Удаление
События объекта DataTable
Объект DataTable содержит ряд событий, которые могут применяться для слежения за происходящими изменениями. Наиболее часто используются следующие события: ColumnChanged - наступает после изменения содержимого поля таблицы; В конструкторе формы предыдущего приложения добавим обработку четырех событий объекта DataTable: public Form1() { В соответствующих методах просто выводим сообщение в текстовое поле: private void dtTours_RowChanging(object sender, DataRowChangeEventArgs e) { Запускаем приложение. Нажимаем кнопку «Begin Edit», затем «End Edit» - происходят события RowChanging и RowChanged. Удаляем запись - происходят события RowDeleting и RowDeleted (рис. 121). Рис. 121. Демонстрация событий таблиц В обработчиках событий можно добавить соответствующие действия, например, подтверждение изменения (RowChanging) или удаления (RowDeleting).
|