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

В отличие от DataGrid, элементы типа DataGridView не позволяют одновременно (с учетом иерархии таблиц) отображать данные двух связанных таблиц. Вместо этого предлагается другая техника отслеживания данных (навигации по данным связанной таблицы). DataBinding следит за перемещением пользователя по записям главной таблицы (Studs), и автоматически перезагружает данные связанной таблицы в момент изменения позиции текущей записи в главной таблице.

Такой синхронный режим функционирования обеих таблиц осуществляется с помощью двух объектов класса BindingSource. Этот класс расширяет возможности технологии Data Binding, с которой вы познакомились ранее. Тогда мы пользовались услугами класса CurrencyManager (cинхронизатора текущей позиции). Теперь ему на смену пришел более мощный класс BindingSource, который поглотил (точнее, инкапсулировал) CurrencyManager. Объект класса BindingSource (обычно в паре с объектом класса BindingNavigator) реализует все рутинные операции, необходимые для отображения связанных данных. BindingSource поддерживает как простое, так и сложное связывание.

¨  Добавьте в класс формы код, который объявляет два связывателя данных (объекта класса BindingSource).

    BindingSource bsStuds, bsExams;

¨  Вставьте код создания и инициализации источников (этот код лучше поместить внутрь метода InitDataSet).

    bsStuds = new BindingSource();

    bsStuds.DataSource = ds;

    bsStuds.DataMember = "Studs";

    bsExams = new BindingSource();

    bsExams.DataSource = bsStuds;

    bsExams.DataMember = "StudExam";

Способ связывания данных определяется свойствами DataSource и DataMember объектов BindingSource. Обратите внимание на различия в значении этих свойств для объектов bsStuds и bsExams. Первый объект привязан к данным таблицы Studs всего контейнера данных (типа DataSet), а второй — к данным своего "старшего брата", пропущенным сквозь фильтр связи "StudExam". Это имя ранее было присвоено объекту типа DataRelation, связывающему две таблицы (DataTable), помещенные в DataSet. Напоминаю, что имена играют решающую роль в механизме DataBinding.

Такие настройки позволяют отслеживать перемещения по строкам главной таблицы (Studs) и отображать результаты экзаменов текущего студента (связанные данные). Для того, чтобы этот механизм заработал, замените источники данных для обеих DataGridView. Вместо набора данных ds задайте:

studsGrid.DataSource = bsStuds;

examsGrid.DataSource = bsExams;

Установку свойств DataMember для обоих DataGridView выключите, так как новые источники данных (bsStuds и bsExams) имеют лишь по одному списку (или таблице) данных и их имена не следует указывать в свойстве DataMember. Запустите приложение и проверьте его работу во всех режимах.

Приведем эквивалентный, но более компактный код создания объектов BindingSource.

bsStuds = new BindingSource(ds, ds.Tables[0].TableName);

bsExams = new BindingSource(bsStuds, ds.Relations[0].RelationName);

В первом варианте мы создавали пустые объекты, а затем настраивали их с помощью свойств. Во втором варианте мы используем другие версии конструкторов, что позволяет обойтись без настроек. Второй вариант компактнее, поэтому произведите замену кода.

BindingNavigator

BindingNavigator предоставляет стандартные способы управления UI (интерфейсом пользователя) тех элементов формы, которые привязаны к источникам данных (BindingSource). Так как навигатор связывания является довольно сложным компонентом, использующим ресурсы, то ввести его в проект лучше с помощью дизайнера студии. Перейдите в режим дизайна формы (Shift+F7) и притащите на нее BindingNavigator. Замените его длинное имя на bn. Так как по умолчанию навигатор улегся на ToolStrip и закрыл ее, то измените значение его свойства Dock на константу перечисления DockStyle.Bottom, или манипулируйте настройками элементов формы так, чтобы и ToolStrip и BindingNavigator были видимы (не закрывали друг друга).