Сложное связывание данных

advertisement
Высокоуровневые методы
информатики и
программирования
Лекция 31
Связывание элементов
управления с данными
План работы
•
•
•
•
•
Источники данных Data Sources
Связывание ЭУ с данными
Класс Binding
Класс BindingSource
Класс BindingNavigator
Связывание элементов управления с
данными
Форма программы
File
Edit
Help
Источник
данных
Элементы
управления
База данных
Источник
данных
Текущие позиции в
источниках данных
Текущие позиции в источниках данных можно изменять
• в элементах управления
• в коде программ: например, в связанном источнике данных свойство Position: ,
для перехода к следующей записи Position++
Источники данных
Data Sources
• Под источником данным понимается множество
данных, с которыми могут быть связаны элементы
управления формы (графического интерфейса).
• Элемент управления является потребителем
данных.
• В платформе .NЕТ Framework источники данных
это любые объекты, у которых реализован
интерфейс IList.
• Источниками данных могут быть:
– массив (array);
– любая обобщенная коллекция;
– объекты ADO:
•
•
•
•
объект класса DataTable;
объект класса DataView;
объект класса DataSet;
объект класса DataViewManager.
Источники данных
• Простые:
– массивы
– коллекции
объектов
встроенных типов.
• Сложные
– массивы объектов
классов;
– коллекций
объектов класса;
– таблицы.
• Составные –
– DataSet (набор
таблиц).
Dataset
Связывание ЭУ с данными
• Связывание с данными (data binding) заключается в
автоматическом занесении (заполнении) в ЭУ данных из
источников данных для их просмотра и модификации. При
изменении данных в ЭУ они также автоматически
переносятся в источник данных.
• Связать с данными можно различные свойства ЭУ.
Например: Size, Location, Color и т.п.
• Типичный пример связывания с данными:
– элемент управления TextBox, связанный с источником
данных.
– он отображает значение некоторого поля в текущей строке
источника данных, к которому привязан.
– при модификации этого поля отображаемое элементом
управления значение также изменится.
Основные классы связывания с
данными
• Два основных класса, которые упрощают сложные
сценарии связывания с данными на форме:
– Класс Binding – для простого связывания отдельных
свойств ЭУ с источниками данных;
– Класс BindingSource – для сложного связывания с
таблицами и связями.
• Эти объекты предоставляют промежуточный
уровень между ЭУ, поддерживающими связывание с
данными, и реальными источниками данных.
• Элемент управления BindingNavigator – для
визуального интерфейса по работе со связанным
источником данных.
Схема связывания с данными
Элемент управления на форме
Связанный источник
данных
Источник данных
Источник данных
Данные
Связывание свойств элементов
управления
• TextBox
Источник данных
– Property
– DataSource
– Position
• ListBox, ComboBox
– DataSource
– DataMember
• DataGridView
– DataSource
Изменении выбранной строки:
• При изменении выбранной строки в ListBox и
DataGridView положение текущей строки
меняется.
• С помощью класса BindingNavigator.
Текущая позиция
Виды связывания с данными
•
•
•
Выделяют следующие виды связывания с данными:
Простое связывание: используется только одно поле источника
данных, последовательно предоставляющее значения связанному с
ним компоненту. Например, элемент управления Label можно связать с
полем объекта DataTable, чтобы он отображал текущее значение поля,
с которым связан.
Сложное связывание: используются несколько записей с одним
элементом управления.
– Например, элементы управления ListBox и ComboBox можно связать с полем
объекта DataTable (или DataView) – они будут отображать во время выполнения
все значения этого поля, а не только текущее.
•
Сложное связывание применяют также для элементов управления,
отображающих набор значений и позволяющих выбрать определенные
строки данных.
– Например: DataGridView, который поддерживает еще более сложный вид
связывания: его можно связать со всеми значениями объекта DataTable,
DataView.
Связывание данных с ЭУ
• Элементы управления TextBox, PictureBox –
используют свойство (коллекцию) DataBindings, для
связывание разных свойств ЭУ с данными из
источника данных;
• Элементы управления ListBox, CheckedListBox,
ComboBox используют свойства:
– Свойство DataSource
– Свойство ValueMember
– Свойство DisplayMember
• Элемент управления DataGridView использует
свойства:
– DataSource = <data set>;
– DataMember = <data table> или <связь с другой
таблицей>
– если задана связь, то в ЭУ показываются записи
таблицы, с которой задана связь.
Простое связывание с данными
• У ЭУ имеется коллекция DataBindings, которая содержит объекты
класса Binding. Каждый объект Binding описывает связь свойства
ЭУ с данными в источнике данных (или связанном источнике
данных).
• В период разработки свойство DataBindings отображается и окне
Properties в виде отдельного узла. Раскрыв его, вы получите доступ
к списку свойств, которые чаще всего связывают с данными.
• Чтобы связать свойство с источником данных нужно:
– щелкните поле рядом с именем свойства - откроется список доступных
источников данных, где объекты DataSet отображаются в виде узлов.
– при раскрытии узла получаем список доступных объектов DataTable и
объектов DataView;
– при раскрытии узел объекта DataView получаем список полей
источника данных;
– при выборе некоторого столбца создается связь между ним и
выбранным свойством элемента управления.
Программное связывание данных
•
Для программного связывания свойств ЭУ с источником данных нужно
добавить в элементе управления описание связывания к коллекции
связей DataBindings.Add(). Есть два основных метод Add().
•
Первый метод добавляет ранее созданный объект класса Binding.
Например:
Binding b = new Binding ("имя свойства", <источник данных>, "имя
свойства или столбца");
DataBindings.Add (b);
•
Второй метод получает три параметра и сам создает объект класса
Binding:
– имя свойства (типа string), которое нужно связать с данными,
– источник данных (объект) и
– путь к элементу объекта источника данных, с которым связывают свойство.
DataBindings.Add("имя свойства", <источник данных>, "имя свойства
или столбца");
Пример простого связывания
• Например: связывание свойства Text элемента управления
TextBox с полем CustomerID таблицы Customers, хранимой в
объекте DataSet с именем ds1:
TextBox1.DataBindings.Add("Text", ds1.Customers, "CustomerID");
• Если связь выполняется с источником данных, который имеют
только один столбец, например, массив, то третьим параметром
будет пустая строка.
• Например:
string[] myStrings = new String[3] { "A ", "String", "Array“};
TextBox1.DataBindings.Add("Text", myStrings, "");
Класс Binding
• Данный класс используется для создания и поддержки простой
связи между
– свойством ЭУ и свойством объекта
• Например , можно связать свойство Text у ЭУ TextBox со свойством FirstName
объекта Customer.
– свойство ЭУ и свойство текущего объекта в списке объектов.
• Например , можно связать свойство Text у ЭУ TextBox со свойством FirstName
объекта DataTable, который содержит объекты Customer.
• Класс Binding также позволяет
– форматировать показываемые значения, с помощью события Format ;
– Преобразовывать отформатированные значения с помощью события
Parse.
• При создании объекта Binding в его конструкторе нужно задать
три параметра:
– Имя свойства ЭУ, которое буде связываться с данными.
– Название источника данных.
– Путь навигационный путь (navigation path), который выдаст список
свойств в источнике данных.
Путь навигации
•
•
•
Разделенный точками путь навигации нужно задавать, когда источником данных
является объект, который содержит несколько объектов DataTable (например, такой,
как DataSet или DataViewManager).
Разделенный точками путь навигации также используется тогда, когда выполняется
связывание с объектом, чьи свойства возвращают ссылки на другие объекты
(например, класс со свойствами, которые возвращают ссылки на другие объекты).
Например, все следующие пути навигации правильно описывают поля данных:
"Size.Height"
"Suppliers.CompanyName"
"Regions.regionsToCustomers.CustomerFirstName"
"Regions.regionsToCustomers.customersToOrders.ordersToDetails.Quantity"
•
Каждый элемент пути навигации может возвращать или свойство, которое имеет
одно значение (такое, как integer) или список значений (такой, как массив строк).
Хотя, каждый элемент пути может быть списком или свойством, конечный элемент
должен быть свойство с одним значением. Каждый следующий элемент стоится на
основе предыдущего элемента:
–
–
"Size.Height" resolves to the Height property for the current Size;
"Regions.regionsToCustomers.CustomerFirstName" resolves to the first name for the current customer, where the
customer is one of the customers for the current region.
События Format и Parse класса
Binding
• Два события класса Binding являются наиболее
важными
– Format - генерируется когда данные передаются из
источника данных в ЭУ;
– Parse - генерируется когда измененные данные передаются
из ЭУ в источника данных.
• При обработке этих событий можно выполнять
дополнительную проверку правильности данных
(validating) и форматирование (formatting) данных.
Пример форматирования и
преобразование
// Нужно форматировать DateOfBirth, для этого задаем обработчики событий
Binding dobBinding = new Binding("Text", custList, "DateOfBirth");
dobBinding.Format += new ConvertEventHandler(this.textBoxDOB_FormatDate) ;
dobBinding.Parse += new ConvertEventHandler(this.textBoxDOB_ParseDate) ;
textBoxDOB.DataBindings.Add(dobBinding);
….
// Format the Date Field to short date form for display in the TextBox
private void textBoxDOB_FormatDate(object sender, ConvertEventArgs e)
{
// We only deal with converting to strings from dates
if (e.DesiredType != typeof(string)) return ;
if (e.Value.GetType() != typeof(DateTime)) return ;
DateTime dt = (DateTime)e.Value;
e.Value = dt.ToShortDateString();
}
// Parse the textbox contents and turn them back into a date
private void textBoxDOB_ParseDate(object sender, ConvertEventArgs e)
{
// We only deal with converting to dates and strings
if (e.DesiredType != typeof(DateTime)) return ;
if (e.Value.GetType() != typeof(string)) return ;
string value = (string)e.Value;
try { e.Value = DateTime.Parse(value); } catch(Exception ex) { MessageBox.Show(ex.Message); }
}
Сложное связывание данных
•
Ряд элементов управления, таких, как ListBox, СоmbоВох или DataGrid, разрешается связать с
несколькими записями одновременно, Такое связывание называется сложным, а элементы
управления, использующие сложное связывание, обычно применяют для отображения нескольких
доступных для выбора записей. Чтобы создать элемент управления, использующий сложное
связывание, установите свойство DataSource элемента управления, поддерживающего такой тип
связывания.
•
В период разработки это можно сделать, установив значение свойства DataSource в окне
Properties.
•
Такие элементы управления, как ListBox, CheckedListBox и ComboBox, способны отображать
несколько записей одновременно, их можно привязать не более чем к одному полю. Для этих
элементов управления необходимо записать в свойство DisplayMember значение типа string,
представляющее имя поля, с которым нужно связать это свойство, например:
ComboBoxl.DataSource = DataSet1.Customers;
ComboBoxl.DisplayMember = "CustomerlD";
•
Элемент управления DataGridView может быть связан с таблицей в DataSet:
DataGrid1.DataSource = DataSet1;
DataGrid1.DataMember = “Customers”;
Связывание списочных элементов с
источниками данных
• У списочных элементов (ListBox, ComboBox,
CheckedListBox) имеются следующие свойства
для связывания с данными:
– свойство DataSource – название таблицы в
DataSet
– свойство DisplayMember – поле источника данных,
значения которого показываются в списке.
– свойство ValueMember – поле источника данных,
значение которого выдается свойством
SelectedValue.
• Например, показываться может название
компании "Customers.CompanyName", а в выдаваться
качестве свойства SelectedValue значение поля
"Customers.CustomerID".
Связывание табличного ЭУ
DataGridView
• Для связывания с данными в ЭУ
DataGridView имеются следующие
свойства:
– DataSource = <data set>;
– DataMember = <data table> или <связь с другой
таблицей>
– если задана связь, то в ЭУ показываются записи
таблицы, с которой задана связь.
Элемент DataGridView
• Основные свойства
– DataSource – подключение источника
данных DataSet;
– DataMember – указание таблицы;
Использование отношений для
связывания с данными
•
•
•
Свойство DataRelation определяет связь записи одной таблицы
DataTable с группой записей в другой таблице DataTable в DataSet.
Если DataSet содержит объекты DataRelation, то можно задать элемент
данных в виде имени таблицы TableName, после которого стоит имя
отношения RelationName, а затем имя колонки в связанной таблице
ColumnName.
Например, если таблица DataTable с именем "Suppliers" содержит
отношение DataRelation с именем "suppliers2products", то элемент
данных может быть задан следующим образом
"Suppliers.suppliers2products.ProductName".
Удаление связи с источником
данных
•
Для удаления связи с источником данных из элемента управления,
нужно вызвать метод DataBindings.Remove(). Этот метод принимает в
качестве параметра объект Binding, который получают из свойства
DataBindings. Например, удаление связывания свойства Text объекта
Label1:
Label1.DataBindings. Remove( Label1.DataBindings["Text"]);
•
При вызове метода DataBindings.Clear() удаляются все связи с
источниками данных у элемента управления:
Label1.DataBindings.Clear();
Класс BindingSource
• Класс BindingSource управляет связыванием с источником данных.
• Объекты данного класса используются для двух целей:
1. Упрощается связывание ЭУ на форме с данными предоставляя дополнительный
опосредованный уровень, управление указателя записи, оповещения об
изменении и другие сервисы
• Для этого BindingSource подключается к источнику данных (свойство DataSource) и
выполняется связывание ЭУ формы с компонентом BindingSource.
• Все дальнейшее взаимодействие с данными (навигация (переход между записями),
сортировка, фильтрация и обновление) выполняется с помощью свойств и методов
BindingSource.
2. объект BindingSource может использоваться, как строго типизированный
источник данных. Обычно тип базового источника данных фиксируется с
помощью:
• Метод Add() для добавления элемента (item) к компоненту BindingSource.
• Свойство DataSource для подключения списка (list), отдельного объекта или типа.
• Объекты BindingSource поддерживают как простое, так и сложное
связывание данных (data binding) с помощью свойств
– Свойство DataSource и
– Свойство DataMember.
Класс BindingSource
• Класс BindingSource позволяет
создать связанный источник
данных, который выступает
посредником между ЭУ и
источником данных.
• Связанный источник данных
позволяет Позволяет:
– Управлять текущей записью с
помощью
Элемент управления
(Control)
BindingSource
(связующий источник)
• свойств Current и Position;
• набора методов: MoveNext(),
MovePrevious, MoveFirst, MoveLast.
–
–
–
–
Фильтрация и сортировка.
Добавление новых записей.
Инициирует события.
….
Источник данных
(Data Source)
Схема связывания с данными
Элемент управления на форме
Связанный источник
данных
Источник данных
Источник данных
Данные
Основные свойства и методы BindingSource
Основные свойства:
• DataSource – источник данных;
• DataMember – при сложном связывании задается путь к данным в источнике
данных (или таблица, или отношение);
• List – коллекция записей …
• Position – положение текущей записи;
• Current – текущая запись …
• Filter – условие отбора записей;
• Sort – условие сортировки записей;
• Count – количество записей;
Основные методы:
• int Add(Object value) – добавить существующую запись;
• public virtual Object AddNew() – добавить новую запись (в ЭУ появляется новая
строка);
• void CopyTo (Array arr, int index) – копировать в массив элементов;
• RemoveAt()
• Clear() – очистить …
• Find() – найти запись по заданному условию …
• MoveFirst(), MoveLast() – перейти к первой или последней записи;
• MoveNext(), MovePrevious() – перейти к следующей или предыдущей записи.
•
Со связанными источниками данных (объектами BindingSource) могут связываться различные
ЭУ формы.
•
Объекты BindingSource используются в качестве промежуточного уровня между коллекциями
(источниками данных) и ЭУ формы (DataGridView или списочными элементами ListBox,
ComboBox).
•
Один объект класса BindingSource (связанный с ListBox) может использоваться в качестве
источника данных для другого объекта BindingSource (связанного с DataGridView), который
реально связан с источником данных.
•
ЭУ Textbox всегда использует для задания связывания объект Binding , который в свою
очередь, может использовать объект BindingSource в качестве источника данных.
Пример создания объектов
BindingSource
• Создание с помощью свойств:
customersBindingSource = new BindingSource();
customersBindingSource.DataSource = ds;
customersBindingSource.DataMember = "Customers";
ordersBindingSource = new BindingSource();
ordersBindingSource.DataSource = customersBindingSource;
ordersBindingSource.DataMember = "RelCustOrd";
• Создание с помощью конструктора:
customersBindingSource =
new BindingSource(northwindDS, "Customers");
detailsBindingSource =
new BindingSource(ordersBindingSource, "RelOrdDet");
Пример удаления элемента
связанного списка
private void button1_Click(object sender, EventArgs e)
{ // создаем строку соединения, адаптер данных и таблицу данных
SqlConnection connectionString = new SqlConnection("Initial Catalog=Northwind;" +
"Data Source=localhost;Integrated Security=SSPI;");
SqlDataAdapter customersTableAdapter =
new SqlDataAdapter("Select * from Customers", connectionString);
DataTable customerTable = new DataTable();
// С помощью адаптера данных заполняем таблицу потребителей.
customersTableAdapter.Fill(customerTable);
// Связываем источник данных со связанным источником данных BindingSource1.
BindingSource1.DataSource = customerTable;
// показываем в тексте метки количество элементов в таблице до удаления элемента.
label1.Text = "Начальное количество: " + BindingSource1.Count.ToString();
// удаляем элемент из таблицы.
BindingSource1.RemoveAt(4);
// показываем новое количество элементов.
label2.Text = “Количество после удаления: " + BindingSource1.Count.ToString();
}
Схема работы компонента BindingSource
Форма
Код
ФИО
Дата
BindingSource
Data Source:
• список
(List)
• таблица
(DataTable)
Position
Управление просмотром записей
• Управление просмотром записей и обновлением элементов
управления, связанных с данными, выполняется при
помощи свойства Position объекта BindingSource.
• Например, для перехода к следующей записи:
bs1.Position++
private void button2_Click(object sender, EventArgs e)
{
if (customersBindingSource.Position < (customersBindingSource.Count - 1))
customersBindingSource.Position++;
}
• Изменение выбранного элемента в ЭУ ListBox,
ComboBox, DataGrid меняет значение текущей записи у
соответствующего источника данных.
Синхронизация связывания с
данными в ЭУ формы
• Часто требуется, чтобы при выборе данных в одном ЭУ, другие ЭУ
показывали информацию, которая связана с выбранным ЭУ.
• Например, при выборе номера группы студентов в ListBox нужно в
DataGridView.
• В приложениях, которые работают с БД часто полезно показывать
записи с группой связанных с ними записей. Отношение Master-Detail.
• Например, можно просматривать Потребителей (Customer) совместно
с их текущими заказами (Orders), которые они сделали. Вместе с
каждым Заказом (Order) также желательно показывать включенные в
него товары (Order Details).
• Если два ЭУ связаны с одним BindingSource, то при изменении
выбранной записи в одном ЭУ, в другом ЭУ выбранная запись также
меняется.
• Если ЭУ подключены к разным BindingSource, которые связаны
между собой через Relation, то они будут отображать
соответствующие данному отношению записи.
Задание связи между записями
•
Задание связи Relationship с именем "RelOrdDet" между полями
Orders.OrderID и OrderDetails.OrderID:
using System.Data;
…
DataRelation relOrdDet;
DataColumn colMaster2;
DataColumn colDetail2;
colMaster2 = ds.Tables["Orders"].Columns["OrderID"];
colDetail2 = ds.Tables["OrderDetails"].Columns["OrderID"];
relOrdDet = new DataRelation("RelOrdDet",colMaster2,colDetail2);
ds.Relations.Add(relOrdDet);
•
Связывание данных с помощью Relationship
BindingSource ordersBindingSource;
…
ordersBindingSource.DataSource = customersBindingSource;
ordersBindingSource.DataMember = "RelCustOrd";
grdOrderDetails.DataSource = ordersBindingSource;
Пример типизированного
DataSet
Связывание источников с помощью
отношения между таблицами
•
Для связывания данных между customersBindingSource и ordersBindingSource
нужно:
–
У первого связанного источника customersBindingSource задать:
• свойству DataSource ссылку на источник данных DataSet
• свойству DataMember задать строку с названием таблицы “Customers”.
• Например:
customersBindingSource = new BindingSource();
customersBindingSource.DataSource = ds;
customersBindingSource.DataMember = "Customers";
–
У второго связанного источника ordersBindingSource задать
• свойству DataSource ссылку на первый связанный источник customersBindingSource
• свойству DataMember задать строку с названием отношения между таблицей “Customers” и
“Orders”
ordersBindingSource = new BindingSource();
ordersBindingSource.DataSource = customersBindingSource;
ordersBindingSource.DataMember = “FK_Orders_Customer";
–
В этом случае второй источник будет содержать только те записи из “Orders”, которые
являются дочерними для записи выбранной в связанном источнике “Customers”.
Элемент управления BindingNavigator
•
•
•
•
Предоставляет визуальный графический интерфейс для работы со
связанным источником данных и отслеживания его изменений.
Для связь с источником данных нужно задать свойству BindingSource ссылку
на объект BindingSource.
Графический интерфейс BindingNavigator состоит из набора ToolStrip кнопок,
текстовых окон и статических текстовых элементов для выполнения
обычных связанных с данными действий, таких как добавление, удаление и
переход между записями данными (элементами источника данных).
Для связь с источником данных нужно задать свойству BindingSource ссылку
на связанный источник данных.
Связывание с данными с
помощью Visual Studio 2008
• Создаем типизированный источник
данных (Data->Add New Data Source…).
• Создаем связанные источники данных
BindingSource и связываем их с
источниками данных и между собой с
помощью свойств.
• Создаем на форме элементы и связываем
с BindingSource.
• При желании можно разместить элемент
BindingNavigator и связать с объектом
BindingSource.
Download