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

Класс DataRowView, также как и DataRow, имеет методы BeginEdit, EndEdit, CancelEdit, и Delete. Эти методы позволяют работать со строками и с отдельными полями данных. Строки можно добавлять, редактировать и удалять. Добавление новой строки, в отличие от DataRow, происходит только после выполнения метода EndEdit. Рассмотрим примеры.

DataTable dt = ds.Tables[0];

DataView view = new DataView(dt);

DataRowView rv = view.AddNew();    // Добавим новую строку

rv["Name"] = "Art Pepper";         // Работает индексатор

rv["Phone"] = "555-7799";

rv["Addr"] = "North st. 33";

rv.EndEdit();

//====== Проверка результата

int last = dt.Rows.Count - 1;

Console.WriteLine (dt.Rows[last]["Name"]);

// rv = view[last];     // Имитируем обновление текущей строки DataRowView

rv.BeginEdit();         // Редактируем текущую строку

rv ["Name"] = "Art Pepper Junior";

rv.EndEdit();

//====== Проверка результата

Console.WriteLine (dt.Rows[last]["Name"]);

rv.Delete();

//====== Проверка результата

Console.WriteLine (dt.Rows[dt.Rows.Count-1]["Name"]);

Думаю, что вы догадались, как наиболее просто проверить эти фрагменты кода. Их можно временно вставить в конец метода Open, где DataSet и его таблицы уже инициализированы.

Метод CreateChildView класса DataRowView позволяет создать новый объект DataView, который является выборкой строк связанной таблицы. В этой выборке содержатся только те строки, которые соответствуют текущей строке главной таблицы. Метод CreateChildView в качестве параметра должен получить либо ссылку на объект DataRelation, либо имя связи между таблицами. Следующий пример иллюстрирует сказанное.

DataView view = new DataView(ds.Tables[0]);

DataView cv = view[0].CreateChildView(ds.Relations[0]);

Console.WriteLine(view[0]["Name"] + "'s exams from the table " + cv.Table.TableName);

for (int i = 0; i < cv.Count; i++)

  Console.WriteLine (cv[i]["Course"] + ", " + cv[i]["Mark"]);

Задание

Добавьте в TollStrip формы кнопку, при нажатии которой создается образ активной таблицы (DataView). Образ должен быть отфильтрован с учетом критерия поиска, заданного в строке comboFind. В процессе обработки события (программным способом) создайте DataGridView grid, поместите его в форму formFound и привяжите его к данным образа таблицы DataView. Для объекта grid добавьте обработку события CellEnter. В реакции на это событие выделяйте цветом те строки таблиц главного окна, которые соответствуют выделенной строке DataGridView вспомогательного окна formFound.

Например, если grid окна с результатами поиска (formFound) отображает результаты экзаменов и в нем активна строка ID=18 studID=5, показанная на рис. A, то в studsGrid и examsGrid должны быть выделены строки, соответствующие studID=5 и ID=18, как показано на рис. B. Перемещение фокуса вверх и вниз по строкам grid должно отслеживаться в обеих таблицах главного окна. Таким образом, пользователь видит как данные студента, экзамен которого отбражен в выделенной строке grid (окна поиска), так и информацию о самом экзамене.

     

                              Рис. A.                                                                                                              Рис. B.

Все предыдущие режимы поиска должны работать, как и прежде. Вспомогательная форма должна создаваться вновь при переключении режимов поиска (ListView или DataGridView). Стиль вспомогательной таблицы grid должен изменяться в зависимости от типа активной таблицы в главном окне, например:

if (activeGrid == studsGrid)

  AddStyleStud(grid);

else

  AddStyleExam(grid);

Приведу один из вариантов решения.

public partial class MainForm : Form

{

  DataSet ds;

  DataGridViewCell activeCell, foundCell;

  bool bFindNext, bSearchChanged;

  string fileName;

  BindingSource bsStuds, bsExams;