Разработка форм Windоws с использованием связанных

advertisement
Ðàçðàáîòêà
ôîðì Windows
ñ èñïîëüçîâàíèåì
ñâÿçàííûõ ýëåìåíòîâ
óïðàâëåíèÿ
 ÝÒÎÉ ÃËÀÂÅ...
•
Óïðàæíåíèå 1.1. Ñîçäàíèå ñâÿçàííîãî
ñïèñêà
•
Óïðàæíåíèå 1.2. Îïðåäåëåíèå ñîñòàâà
äàííûõ, îòîáðàæàåìûõ â ñâÿçàííîì
ñïèñêå
•
Óïðàæíåíèå 1.3. Ñâÿçûâàíèå
è ïðîñìîòð îòäåëüíûõ òåêñòîâûõ
ïîëåé ñ îòñ÷åòîì îò âûáðàííîãî
ýëåìåíòà ñïèñêà
•
Óïðàæíåíèå 1.4. Ðåäàêòèðîâàíèå
è îáíîâëåíèå äàííûõ
ñ èñïîëüçîâàíèåì ñâÿçàííûõ
ýëåìåíòîâ óïðàâëåíèÿ
•
Óïðàæíåíèå 1.5. Äîáàâëåíèå
è óäàëåíèå çàïèñåé ñ èñïîëüçîâàíèåì
ñâÿçàííûõ ýëåìåíòîâ óïðàâëåíèÿ
•
Óïðàæíåíèå 1.6. Îáðàáîòêà îøèáîê
ñ ïîìîùüþ ñâÿçàííûõ ýëåìåíòîâ
óïðàâëåíèÿ
•
Óïðàæíåíèå 1.7. Îêîí÷àòåëüíîå
îôîðìëåíèå ôîðìû, ñâÿçàííîé
ñ äàííûìè
•
Óïðàæíåíèå 1.8. Ñâÿçûâàíèå äàííûõ
ñ ýëåìåíòàìè óïðàâëåíèÿ ComboBox
è DataGrid
•
Óïðàæíåíèå 1.9. Ïîâûøåíèå ñòåïåíè
äåòàëèçàöèè ïðåäñòàâëåíèÿ äàííûõ
â ýëåìåíòå óïðàâëåíèÿ DataGrid
ÃËÀÂÀ
1
24
Глава 1
Visual Basic .NET — это один из языков, который входит в поставку программного
продукта Visual Studio .NET. Он является гораздо более мощным по сравнению с язы
ком Visual Basic 6.0. В этом можно убедиться, прочитав настоящую книгу.
В предыдущих версиях Visual Basic для привязки элементов управления к данным нуж
но было ввести в программу определенный код вручную; для этого приходилось выпол
нять более значительный объем работы по сравнению с использованием связанных эле
ментов управления. Но в этих версиях применение элементов управления, связанных с
данными, было затруднительным, поскольку они не обеспечивали полный контроль над
процессом обработки данных. Подготавливая к выпуску версию языка VB.NET, корпора
ция Microsoft проделала очень большую работу. Были созданы не только развитые элемен
ты управления, связанные с данными, но и обеспечена возможность автоматической ге
нерации необходимого кода при размещении в форме связанных с данными элементов
управления, поскольку организация всех языков .NET основана на использовании классов.
В предыдущих версиях Visual Basic для создания баз данных небольшого и среднего
объема в основном применялась машина базы данных Microsoft Jet, и в книгах, подобных
этой, как правило, рассматривался способ доступа к данным, основанный на ее использо
вании. Теперь в поставку программного обеспечения языка Visual Basic входит версия сер
вера Microsoft SQL Server 2000 для настольного компьютера (MSDE — Microsoft SQL
Server 2000 Desktop Edition). Это — упрощенная версия сервера SQL Server 2000, позво
ляющая разрабатывать базы данных на одном компьютере, а эксплуатировать — на другом.
При этом на компьютере может быть установлена либо однопользовательская локальная
версия MSDE, либо полнофункциональная версия SQL Server 2000. В настоящей книге по
казано, как использовать базу данных SQL Server в программе Visual Studio и в конкретных
приложениях. В частности, здесь описан способ создания утилит для подключения к но
вым базам данных, а также для резервного копирования и восстановления баз данных.
Хотя в настоящей книге в качестве базы данных используется MSDE, для перехода на
другую версию базы данных достаточно откорректировать свойство ConnectionString
объекта OleDbConnection в формах и свойство ConnectionString объекта
OleDbConnection, рассматриваемое в главе 4, “Манипулирование данными в среде
ADO.NET”. Обратите внимание, что в коде, приведенном в указанной выше главе, имеется
закомментированная строка, которая показывает, как использовать версию базы данных
Northwind на основе машины баз данных Jet.
Óïðàæíåíèå 1.1. Ñîçäàíèå ñâÿçàííîãî
ñïèñêà
Обычно при создании формы базы данных применялся подход, при котором дос
таточно было связать с элементом данных набор записей и дать возможность пользо
вателям выполнять прокрутку строк с данными, а также вносить в них изменения по
мере необходимости. Но такой подход не всегда оправдывается при создании прило
жений клиент/сервер или Webприложений.
Дело в том, что следует, прежде всего, обеспечить возможность ограничения объ
ема данных, предоставляемых пользователям, чтобы они могли выбирать только те
записи, которые необходимо редактировать или просматривать. Это позволяет не
передавать все поля таблицы по локальной сети или по Internet. Для этой цели могут
применяться элементы управления списком и полем со списком. В настоящем упраж
Разработка форм Windows с использованием связанных элементов...
25
нении показано, как применяются в программных приложениях два элемента управ
ления данными: OleDbDataAdapter и DataSet. Эти элементы управления дают воз
можность заполнить список с помощью единственной строки кода.
Предположим, что необходимо обеспечить просмотр списка пользователей в
форме Windows с помощью элемента управления ListBox. На данном этапе решения
этой задачи не разрабатывается программа. Создается только прототип формы, по
этому достаточно применить связанные с данными элементы управления. Рассмотрим
способ создания списка и связывания его с данными с помощью элементов управле
ния данными.
Îáùåå îïèñàíèå
Прежде чем приступить к изучению объектов, применяемых для представления
данных в среде .NET, необходимо рассмотреть пространства имен .NET и способы их
использования.
Ïðèìåíåíèå ïðîñòðàíñòâ èìåí .NET
Инфраструктура .NET содержит большую библиотеку классов, которая состоит из
множества пространств имен. Эти пространства имен включают разнообразные клас
сы, позволяющие создавать в программе собственные объекты. В пространствах имен
представлены все объекты и классы, которые входят в состав таких объектов .NET,
как формы, элементы управления и всевозможные объекты данных.
Пространство имен может, в свою очередь, состоять из других пространств имен.
Например, пространство имен System.Data включает не только собственные клас
сы, такие как DataSet и DataTable, но и пространства имен System.Data.OleDb,
System.Data.SQLClient и т.д. Для ознакомления с пространствами имен .NET вы
берите команду Object Browser в меню View. Затем можно раскрыть пространство
имен System.Data для просмотра содержащихся в нем пространств имен.
Если известно, что в качестве базы данных для приложения должна использовать
ся база данных SQL Server, то для обеспечения более высокой производительности
этого приложения следует применять классы, которые относятся к пространству
имен System.Data.SQLClient. Но если тип базы данных, применяемой в приложе
нии, заранее не известен, то следует использовать классы пространства имен
System.Data.OleDb.
В настоящей книге используются объекты, созданные с помощью классов про
странства имен System.Data.OleDb. Поэтому представленные здесь процедуры мо
гут применяться для работы с другими базами данных без значительной доработки.
Совет
Åñëè èçâåñòíî, ÷òî â ïðèëîæåíèè â êà÷åñòâå áàçû äàííûõ ïðèìåíÿåòñÿ áàçà
äàííûõ SQL Server, òî â ýòîì ïðèëîæåíèè ñëåäóåò èñïîëüçîâàòü ýëåìåíòû
óïðàâëåíèÿ äàííûìè òèïà SQL Server, ïîñêîëüêó îíè îïòèìèçèðîâàíû äëÿ ðàáîòû èìåííî ñ íåé.
Для создания форм Windows предназначено восемь элементов управления данны
ми. В табл. 1.1 перечислены эти элементы управления и описано их назначение. Что
бы получить к ним доступ, щелкните на группе элементов Data панели инструментов.
26
Глава 1
Òàáëèöà 1.1. Ýëåìåíòû óïðàâëåíèÿ äàííûìè, ïðèìåíÿåìûå äëÿ ñîçäàíèÿ
ôîðì Windows
Элемент управления
Назначение
DataSet
Используется в сочетании с другими элементами управления дан
ными; он позволяет сохранить результаты, возвращенные команда
ми и адаптерами данных DataAdapter. В отличие от наборов запи
сей, применяемых в технологиях ADO и DAO, элемент управления
DataSet фактически позволяет вернуться к иерархическому пред
ставлению данных. Свойства и коллекции объекта DataSet дают
возможность получить полный доступ к отдельным таблицам, стро
кам и столбцам
OleDbDataAdapter
Дает возможность управлять командами, которые должны быть приме
нены к такому провайдеру данных OleDb, как Jet, Oracle или SQL Server,
и хранить их. В частности, могут применяться команды выборки, об
новления, вставки и удаления записей. Отслеживается также объект со
единения Connection, к которому применяются эти команды
OleDbConnection
Позволяет сопровождать информацию о соединении для провайде
ра данных OleDb. Он применяется в сочетании с элементом управ
ления OleDbDataAdapter
OleDbCommand
Как и объект команды ADO, позволяет передавать в базу данных
операторы SQL или хранимые процедуры для выполнения трудо
емких операций или выборки данных
SqlDataAdapter
Аналогичен OleDbDataAdapter за исключением того, что он при
меняется для доступа только к хранилищам данных SQL Server
SqlConnection
Аналогичен OleDbConnection за исключением того, что он при
меняется для доступа только к хранилищам данных SQL Server
SqlCommand
Аналогичен OleDbCommand за исключением того, что он применя
ется для доступа только к хранилищам данных SQL Server
DataView
Позволяет создать несколько представлений одной и той же табли
цы. В частности, он обеспечивает возможность просматривать дан
ные, находящиеся в различных состояниях, например, удаленные,
модифицированные или отсортированные различным образом
Ниже показано, как создать элементы управления данными двух описанных выше ти
пов, OleDbDataAdapter и DataSet, и связать их с элементом управления списком для
отображения перечня заказчиков. Следует отметить, что при этом создается также эле
мент управления OleDbConnection, но эта операция выполняется в среде Visual Studio
.NET. После этого достаточно ввести одну строку кода, чтобы заполнить набор данных.
Ïîðÿäîê äåéñòâèé
Для предварительного просмотра результатов этого упражнения откройте прило
жение VB.NET - Chapter1, которое находится в папке данной главы (см. следующее
примечание). Сразу после вызова на выполнение проекта этого приложения откры
вается форма, с помощью которой можно получить доступ к материалам всех упраж
нений, рассматриваемых в данной главе. Щелкните на элементе How-To 1.1, чтобы
открыть форму для упражнения 1.1 (рис. 1.1).
Разработка форм Windows с использованием связанных элементов...
27
Ðèñ. 1.1. Главная форма и форма HowTo 1.1 из первого упражнения этой главы
Примечание
Èñõîäíûé êîä óïðàæíåíèé êî âñåì ãëàâàì ýòîé êíèãè ïðåäñòàâëåí íà ñîïðîâîæäàþùåì Web-óçëå www.samspublishing.com. Ïåðåéäèòå ïî óêàçàííîìó àäðåñó,
óêàæèòå â êà÷åñòâå ïîèñêîâîé ñòðîêè ISBN àíãëîÿçû÷íîãî èçäàíèÿ (0672322471)
è çàãðóçèòå àðõèâ ñ èñõîäíûì êîäîì è ãîòîâûìè ïðèëîæåíèÿìè.
1. Создайте новый проект Visual Studio .NET с использованием шаблона проекта
Windows Application. В результате будет создана начальная форма с именем
Form1, которая используется и в дальнейшем.
2. Перетащите на форму элемент управления OleDbDataAdapter из группы эле
ментов Data Controls, находящейся на панели инструментов. Откроется окно мас
тера настройки конфигурации адаптера данных Data Adapter Configuration
Wizard. Прочитайте вступительный текст на экране, а затем щелкните на кнопке
Next, чтобы выбрать соединение данных. Если в данный момент вы не можете
найти соединение данных с базой данных Northwind в раскрывающемся списке
соединений данных, щелкните на кнопке New Connection. После этого откроется
диалоговое окно свойств канала передачи данных Data Link Properties, знакомое
тем, кто уже использовал другие программные продукты Microsoft, такие как
Visual Studio 6.0. Укажите в качестве имени сервера (local), выберите пере
ключатель Use Windows NT Integrated Security, который обеспечивает использо
вание встроенных средств защиты Windows NT, укажите в качестве базы данных
Northwind (рис. 1.2) и щелкните на кнопке OK.
3. После этого снова откроется страница выбора соединения данных Choose Your
Data Connection программы Data Adapter Configuration Wizard, на которой в
раскрывающемся списке Data Connection будет отмечена база данных
Northwind. Щелкните на кнопке Next. Теперь откроется страница, позволяю
щая выбрать тип запроса, на использовании которого будет основан приме
няемый адаптер данных. Оставьте предусмотренное по умолчанию значение
Use SQL Statements (Использовать операторы SQL) и щелкните на кнопке
Next. Откроется поле ввода, обозначенное вопросом What Data Should the Data
Adapter Load into the Dataset? (Какие данные должны загружаться этим адапте
ром данных в набор данных?) Введите в этом поле следующее:
Select CustomerID, CompanyName From Customers
28
Глава 1
Ðèñ. 1.2. Соединение данных, которое
в дальнейшем будет использоваться по
умолчанию в окне Server Explorer
программы Visual Studio .NET на
этом компьютере
Примечание
Ïî óìîë÷àíèþ ïðîãðàììà-ìàñòåð Data Adapter Configuration Wizard ñîçäàåò îïåðàòîðû SQL íå òîëüêî äëÿ âûáîðêè (ïðîñìîòðà) äàííûõ, íî òàêæå äëÿ âñòàâêè, îáíîâëåíèÿ è óäàëåíèÿ äàííûõ. Åñëè âû õîòèòå èñïîëüçîâàòü â ñâîèõ ïðèëîæåíèÿõ òîëüêî
ñðåäñòâà âûáîðêè äàííûõ, òî ùåëêíèòå íà êíîïêå Advanced Options
(Äîïîëíèòåëüíûå îïöèè) â ëåâîì íèæíåì óãëó ýòîãî äèàëîãîâîãî îêíà. Ñíèìèòå
îòìåòêó ñ ôëàæêà Generate Insert, Update, and Delete statements. Â ðàññìàòðèâàåìîì
ïðèëîæåíèè îïåðàòîðû Insert, Update è Delete íå òðåáóþòñÿ, ïîñêîëüêó äàííûå
â íåì ïðèìåíÿþòñÿ òîëüêî äëÿ çàïîëíåíèÿ ýëåìåíòà óïðàâëåíèÿ ListBox. Ùåëêíèòå íà êíîïêå OK, ÷òîáû çàêðûòü äèàëîãîâîå îêíî Advanced Options.
4. Щелкните на кнопке Next для просмотра результатов выполнения оператора
выборки, как показано на рис. 1.3. Если внешний вид окна будет отличаться от
показанного на рис. 1.3, это означает, что вы неправильно ввели оператор
Select или не отменили использование дополнительных опций.
5. Щелкните на кнопке Finish, чтобы создать адаптер данных и объект соединения.
Затем на экране появится новый элемент адаптера данных, обозначенный как
OleDbDataAdapter1, и элемент управления соединением OleDbConnection1.
Оба эти элементы управления находятся в области Components в нижней части ок
на Form Designer.
6. После создания первых двух элементов управления необходимо перейти к созда
нию объекта Dataset. Щелкните правой кнопкой мыши на команде Data Adapter и
выберите элемент Generate Dataset из всплывающего меню. Откроется диалоговое
окно Generate Dataset. Оставьте неизменными все значения, предусмотренные по
Разработка форм Windows с использованием связанных элементов...
29
умолчанию, и просто щелкните на кнопке OK, чтобы создать элемент управления
набором данных, обозначенный как DataSet<number>. (Порядковый номер
<number> увеличивается по мере создания новых элементов управления набором
данных.)
7. Теперь можно приступить к созданию элемента управления ListBox. Перета
щите на форму элемент управления ListBox из группы элементов Windows
Forms панели инструментов. Растяните окно этого элемента управления до
размеров формы, а затем задайте для элемента управления ListBox значения
свойств, приведенные в табл. 1.2.
Ðèñ. 1.3. Пример успешного создания адаптера данных
Òàáëèöà 1.2. Çíà÷åíèÿ ñâîéñòâ ýëåìåíòà óïðàâëåíèÿ ListBox, íåîáõîäèìûå
äëÿ ñâÿçûâàíèÿ åãî ñ ýëåìåíòîì óïðàâëåíèÿ DataSet
Свойство
Значение
DataSource
DataSet<Number>
DisplayMember
Customers.CompanyName
ValueMember
Customers.CustomerID
Хотя этот набор данных правильно связан со свойствами элемента управления
ListBox, в данный момент после вызова формы на выполнение в ней откроет
ся пустой элемент управления ListBox.
8. На данном этапе выполнения рассматриваемого упражнения осталось ввести в об
работчик событий Load формы единственную строку кода. Щелкните на кнопке
View Code в окне Solutions Explorer или выберите команду Code в меню View. В окне
Code Editor выберите из раскрывающегося списка имен классов Class Name строку,
соответствующую основным объектам класса (Base Class Objects), а затем выбери
те Load из раскрывающегося списка Methods. После этого введите приведенную
ниже строку кода, представляющую собой команду для адаптера данных, согласно
которой он должен заполнить данными набор данных:
30
Глава 1
OleDbDataAdapter1.Fill(DataSet1)
Проследите за тем, чтобы в этой команде использовались имена созданных ва
ми элементов управления. В листинге 1.1 приведен код обработчика событий
Load для формы frmHowTo1_1, используемой в этих примерах.
Ëèñòèíã 1.1. frmHowTo1_1.vb — çàïîëíåíèå íàáîðà äàííûõ, ñ êîòîðûì ñâÿçàí
ýëåìåíò óïðàâëåíèÿ ListBox1
Private Sub frmHowTo1_1_Load(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
Me.OleDbDataAdapter1.Fill(Me.DataSet1)
End Sub
Îïèñàíèå ïîëó÷åííûõ ðåçóëüòàòîâ
После загрузки формы frmHowTo1_1 вызывается метод Fill элемента управления
OleDbDataAdapter1 и ему передается набор данных DataSet1. Поскольку в качестве
значения свойства DataSource элемента управления ListBox1 указано имя
DataSet1, а значения свойств ValueMember и DisplayMember заданы соответст
вующим образом, то элемент управления ListBox1 заполняется данными из столбцов
CustomerID и CompanyName таблицы Customers базы данных Northwind. На рис. 1.4
показано, какой окончательный вид имеет эта форма в окне программы Designer, а на
рис. 1.5 показано, какой вид она принимает после вызова ее на выполнение.
Ðèñ. 1.4. Окончательный вид проекта первого упражнения по использованию базы данных
Разработка форм Windows с использованием связанных элементов...
31
Ðèñ. 1.5. Список, содержащий данные
таблицы Customers базы данных
Northwind SQL Server
Êîììåíòàðèè
При разработке версии языка Visual Basic для инфраструктуры .NET корпорация
Microsoft предприняла значительные усилия по обеспечению надежного функциониро
вания элементов управления данными. Одной из замечательных особенностей новых
версий элементов данных является то, что пользователь имеет возможность проследить
за выполнением большинства задач с помощью языка Visual Basic .NET. Даже если
функционирование элементов управления данными, размещенных в форме, обеспечи
вается автоматически, при этом в среде Visual Studio создается код, выполняющий соот
ветствующие действия. Для просмотра этого кода можно щелкнуть на элементе
#Region, который выглядит примерно так:
#Region " Windows Form Designer generated code "
Следует учитывать, что под этим элементом представлен большой объем кода, и
разработчик не должен вносить в него изменения. Но изучение такого кода позволяет
узнать очень многое.
По мере дальнейшего использования представленных здесь элементов управления
данными вы успешно освоите основные способы модификации различных свойств
этих элементов управления и узнаете, какие возможности они предоставляют.
Óïðàæíåíèå 1.2. Îïðåäåëåíèå ñîñòàâà
äàííûõ, îòîáðàæàåìûõ â ñâÿçàííîì
ñïèñêå
Если в таблице содержится много данных, то заполнение списка данными даже из
нескольких столбцов требует больших затрат вычислительных ресурсов. В этом уп
ражнении показано, как создать параметризованный оператор SQL для ограничения
количества элементов, отображаемых в списке, что позволяет уменьшить потреб
ность в ресурсах и тем самым повысить производительность выполнения форм.
Предположим, что в базе данных содержатся данные о сотнях тысяч заказчиков и
поэтому не следует загружать в элемент управления списком сразу всю таблицу заказ
чиков. Ниже описаны способы ограничения объема данных, отображаемых в списке.
32
Глава 1
Îáùåå îïèñàíèå
Прежде всего, необходимо сделать копию формы, созданной в упражнении 1.1.
Затем в форму нужно ввести элементы управления Label и TextBox, из которых в
оператор Select, содержащийся в элементе управления OleDbDataAdapter, будет
поступать информация, позволяющая ограничить объем данных, отображаемых в
списке. Кроме того, в форму будет введена кнопка, позволяющая вызывать метод
Fill элемента управления OleDbDataAdapter после каждого обновления содержи
мого текстового поля и щелчка на ней (рис. 1.6).
Ðèñ. 1.6. Форма, позволяющая ограничить
объем данных, загружаемых в список
Ïîðÿäîê äåéñòâèé
Чтобы приступить к выполнению этого упражнения, щелкните правой кнопкой
мыши на форме, созданной в упражнении 1.1, которая должна быть указана в перечне
форм окна Solutions Explorer. Выберите команду Copy из всплывающего меню. Затем
щелкните правой кнопкой мыши на этом проекте в окне Solutions Explorer и выберите
команду Paste из всплывающего меню. Теперь в окне Solutions Explorer появится но
вый объект Class с именем Copy Of<предыдущее имя формы>. Присвойте вновь соз
данной форме произвольное имя. Затем выделите подсветкой эту форму и щелкните
на кнопке Code в верхней части окна Solutions Explorer. Откорректируйте первую
строку кода следующим образом:
Public Class <новое имя формы>
Вполне очевидно, что эта строка кода не была откорректирована в среде VS авто
матически после изменения имени формы. Дело в том, что разработчик мог просто
создать дубликат определения объекта Class, поэтому такая корректировка не долж
на выполняться автоматически.
После этого вы обнаружите, что пиктограмма рассматриваемой формы имеет пра
вильное имя. Теперь можно приступить к выполнению дальнейших этапов этого уп
ражнения.
1. Выберите созданный вами адаптер данных. В области окна Properties после
щелчка на знаке “плюс” (+) рядом со свойством SelectCommand будет показано
свойство CommandText. Замените текущее значение свойства CommandText
(Текст команды) следующей командой:
Разработка форм Windows с использованием связанных элементов...
33
SELECT CustomerID, CompanyName FROM Customers
WHERE (CompanyName LIKE ? + '%')
Дополнительная информация об операторе Select представлена в главе 3,
“Просмотр данных с применением средств ADO.NET”. Однако отметим, что в при
меняемой здесь конструкции WHERE предусмотрено сравнение содержимого поля
CompanyName с заданным параметром, как показывает применяемая здесь опера
ция, обозначенная как ? (вопросительный знак). Это действие выполняется с ис
пользованием кода, который будет рассматриваться на последнем этапе данного
упражнения. Знак процента (%) представляет собой подстановочный символ, кото
рый указывает серверу, что должен быть выполнен поиск подстроки.
2. Измените размеры окна элемента управления ListBox и освободите место в
верхней части формы для элементов управления Label, TextBox и Button.
Создайте эти три элемента управления и откорректируйте значения их
свойств, как показано в табл. 1.3.
Òàáëèöà 1.3. Çíà÷åíèÿ ñâîéñòâ ýëåìåíòîâ óïðàâëåíèÿ Label, TextBox è Button
Объект
Свойство
Значение
Label
Text
Customer
TextBox
Name
txtCustLimit
Text
A
Name
btnLoadList
Text
Load List
Button
3. Дважды щелкните на вновь созданной кнопке, обозначенной как btnLoadList.
Введите в обработчик событий Click кнопки btnLoadList код, приведенный в
листинге 1.2. Этот код загружает данные, введенные в поле txtCustLimit, в па
раметр OleDBDataAdapter1, который был создан с помощью операции ? в опе
раторе Select адаптера данных. После этого происходит уничтожение всех дан
ных, хранящихся в наборе данных Dataset1, с помощью метода Clear. И нако
нец, объект DataSet1 снова заполняется данными с учетом значения
txtCustLimit; для этого применяется адаптер данных.
Ëèñòèíã 1.2. frmHowTo1_2.vb — ïåðåäà÷à ïàðàìåòðà îáúåêòó DataAdapter
è çàïîëíåíèå íàáîðà äàííûõ
Private Sub btnLoadList_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles _
btnLoadList.Click
Me.OleDbDataAdapter1.SelectCommand.Parameters(0).Value = _
Me.txtCustLimit.Text
Me.DataSet1.Clear()
Me.OleDbDataAdapter1.Fill(Me.DataSet1)
End Sub
4. Выделите подсветкой и удалите из формы обработчик событий Load, посколь
ку здесь не ставится задача заполнять форму, перехватывая это событие при ее
34
Глава 1
загрузке. В данном случае предусмотрено, что пользователь должен щелкнуть
на кнопке btnLoadList.
Примечание
Ìåæäó ýëåìåíòàìè óïðàâëåíèÿ OleDbDataAdapter è SqlDataAdapter åñòü
îäíî âàæíîå ðàçëè÷èå. Ýëåìåíò óïðàâëåíèÿ OleDbDataAdapter ïðåäóñìàòðèâàåò èñïîëüçîâàíèå îïåðàöèè ? äëÿ óêàçàíèÿ ïàðàìåòðà â îïåðàòîðå Select, à
äëÿ ýëåìåíòà óïðàâëåíèÿ SqlDataAdapter òðåáóåòñÿ èìåíîâàííûé ïàðàìåòð,
òàêîé êàê @parCustLimit. Ïîýòîìó âìåñòî óêàçàííîãî â øàãå 1 ñëåäóþùåãî
îïåðàòîðà Select:
SELECT CustomerID, CompanyName FROM Customers WHERE (CompanyName
LIKE ? + '%')
ïðèìåíÿåòñÿ îïåðàòîð Select â òàêîé ôîðìå:
SELECT CustomerID, CompanyName FROM Customers WHERE (CompanyName
LIKE @parCustLimit + '%')
Ïðè ýòîì ôàêòè÷åñêè ïðèìåíÿåìîå èìÿ ïàðàìåòðà çàâèñèò îò êîíêðåòíîé ïðîãðàììû.
Îïèñàíèå ïîëó÷åííûõ ðåçóëüòàòîâ
После загрузки формы, созданной в этом упражнении, или вызова на выполнение
формы frmHowTo1_2 появляются пустой элемент управления ListBox и располо
женное над ним текстовое поле с введенной в нем буквой A. После щелчка на кнопке
btnLoadList окно списка загружается значениями, которые соответствуют букве
(или буквам), введенной в элементе управления txtCustLimit, с помощью кода,
описанного в шаге 3.
Êîììåíòàðèè
Попытайтесь ввести несколько других букв, а затем очистить поле ввода. При этом ко
личество отображаемых строк уменьшается по мере увеличения количества введенных
букв, а если в текстовом поле не введено ни одной буквы, отображаются все записи.
Описанный здесь метод является простым, но достаточно мощным и может при
меняться во многих приложениях.
Рассматриваемая форма будет использоваться еще в нескольких упражнениях. Вы
можете скопировать эту форму и на ее основе начать разработку новой, как описано в
начале данного упражнения. Еще один вариант состоит в том, что ко времени выпол
нения упражнения 1.8 будет разработана форма ввода данных, которую можно ис
пользовать в дальнейшей работе. Тем не менее для каждого упражнения, описанного
в этой главе, имеется готовое решение.
Разработка форм Windows с использованием связанных элементов...
35
Óïðàæíåíèå 1.3. Ñâÿçûâàíèå
è ïðîñìîòð îòäåëüíûõ òåêñòîâûõ
ïîëåé ñ îòñ÷åòîì îò âûáðàííîãî
ýëåìåíòà ñïèñêà
В настоящем упражнении на примере списка, аналогичного описанному в пре
дыдущем упражнении, будет показано, как создать дополнительные объекты
OleDbDataAdapter и DataSet и связать их с отдельными текстовыми полями для
просмотра данных.
Списки являются удобным средством отображения ряда полей формы и ограни
чения количества выводимых строк, но иногда возникает необходимость ознако
миться с подробными сведениями, представленными в отдельных текстовых полях,
выполнив щелчок на элементе в списке.
Îáùåå îïèñàíèå
На данном этапе дорабатывается форма, созданная в упражнении 1.2; в эту фор
му вводятся дополнительные элементы управления данными, в частности, еще один
адаптер данных и набор данных. Здесь также показано, как ввести в новый адаптер
данных оператор Select, который принимает в качестве параметра выбранный
элемент списка. После этого набор данных заполняется данными и в текстовых по
лях отображаются поля текущей записи, полученные с использованием рассматри
ваемого набора данных в качестве источника данных. Пример полученных резуль
татов показан на рис. 1.7.
Ðèñ. 1.7. Пример связывания с набором данных текстовых
полей, а не списков
Ïîðÿäîê äåéñòâèé
В процессе дальнейшей разработки рассматриваемой формы необходимо переимено
вать адаптер данных, набор данных и список, которые в настоящее время представлены в
форме, и присвоить им более содержательные имена, которые приведены в табл. 1.4.
Глава 1
36
Òàáëèöà 1.4. Èçìåíåíèÿ, âíåñåííûå â îáúåêòû, êîòîðûå â íàñòîÿùåå âðåìÿ
ïðåäñòàâëåíû â ôîðìå
Объект
Свойство
Старое значение
Новое значение
ListBox
Name
ListBox1
lstCustomers
OleDbDataAdapter
Name
OleDbDataAdapter1
odaCustomerList
DataSet
Name
DataSet1
dsCustomerList
Совет
Ïðèñâàèâàéòå èìåíà îáúåêòàì íåïîñðåäñòâåííî âî âðåìÿ èõ ñîçäàíèÿ. Ýòà ðåêîìåíäàöèÿ îòíîñèòñÿ êî âñåì ïðîãðàììàì, ïðîåêòàì è ôîðìàì, à òàêæå ê
ýëåìåíòàì óïðàâëåíèÿ, êîòîðûå èñïîëüçóþòñÿ â ôîðìàõ. ßçûêè, ïðèìåíÿåìûå
â ñðåäå .NET, ÿâëÿþòñÿ îáúåêòíî-îðèåíòèðîâàííûìè è îáåñïå÷èâàþò àâòîìàòè÷åñêóþ âûðàáîòêó áîëüøîãî îáúåìà êîäà, ïîýòîìó ïðîöåññ ïåðåèìåíîâàíèÿ
îáúåêòîâ ïîñëå èõ ñîçäàíèÿ ÿâëÿåòñÿ âåñüìà ñëîæíûì.  ÷àñòíîñòè, åñëè òàêîå
ïåðåèìåíîâàíèå âûïîëíÿåòñÿ â ñðåäå Visual Studio, òî, ïî-âèäèìîìó, ïðè ýòîì
íå ó÷èòûâàþòñÿ âñå ó÷àñòêè êîäà, êîòîðûå äîëæíû áûòü îòêîððåêòèðîâàíû. Â
êà÷åñòâå íàãëÿäíîãî ïðèìåðà ìîæíî óêàçàòü ïåðåèìåíîâàíèå ôîðìû.  ÷àñòíîñòè, íàïîìíèì, ÷òî íàì ïðèøëîñü îòêîððåêòèðîâàòü â êîäå îïåðàòîð Public
Class, ÷òîáû îí ñîîòâåòñòâîâàë íîâîìó èìåíè ôîðìû.
1. Перетащите на форму еще один элемент управления Data Adapter, взяв его из
группы Data на панели инструментов. Примените существующее соединение
данных, укажите, что будут применяться операторы SQL, и присвойте этому эле
менту управления следующий оператор Select, в котором используется пара
метр, заданный во время выполнения с помощью выбранного элемента списка.
SELECT CustomerID, CompanyName, ContactName, ContactTitle, Address,
City, Region, PostalCode, Country, Phone, Fax FROM Customers
WHERE (CustomerID = ?)
После этого щелкните на кнопке Advanced Options на странице с оператором
Select и отмените опцию создания операторов Insert, Update и Delete. За
вершите работу в программе Data Adapter Wizard и переименуйте элементы
управления odaCustomerIndividual.
2. Щелкните правой кнопкой мыши на элементе odaCustomerIndividual и вы
берите команду Generate Dataset из всплывающего меню. Создайте новый на
бор данных dsCustomerIndividual. Щелкните на кнопке OK. Ко времени на
писания данной книги в среде VS предусматривалось размещение символа 1 в
конце имени указанного набора данных. Откорректируйте это имя, удалив сим
вол 1. Теперь в вашей форме должно быть два адаптера данных
(odaCustomerList и odaCustomerIndividual) и два набора данных
(dsCustomerList и dsCustomerIndividual).
3. На этом этапе необходимо ввести текстовые поля. Откорректируйте размеры
формы, чтобы в нее можно было добавить столбец, состоящий из текстовых
полей с надписями рядом с ними. Затем введите надписи и текстовые поля;
укажите в качестве свойства Text текстовых полей имена столбцов в таблице
Customers, к которым предоставляется доступ с помощью набора данных
dsCustomerIndividual. Свойство Text текстовых полей относится к катего
Разработка форм Windows с использованием связанных элементов...
37
рии Data Binding, представленной в окне свойств. В табл. 1.5 перечислены эле
менты управления и значения их свойств. Пример размещения элементов
управления приведен на рис. 1.8.
Òàáëèöà 1.5. Çíà÷åíèÿ ñâîéñòâ íîâûõ ýëåìåíòîâ óïðàâëåíèÿ Label è TextBox
äëÿ ôîðìû frmHowTo1_3
Объект
Свойство
Значение
Label
Text
Customer ID
Label
Text
Company Name
Label
Text
Contact
Label
Text
Contact Title
Label
Text
Address
Label
Text
City
Label
Text
Region
Label
Text
Country
Label
Text
Phone
Label
Text
Fax
TextBox
Name
txtCustomerID
Text
dsCustomerIndividual - Customers.CustomerID
TextBox
Name
txtCompanyName
Text
dsCustomerIndividual - Customers.CompanyName
TextBox
Name
txtContact
Text
dsCustomerIndividual - Customers.Contact
TextBox
Name
txtContactTitle
Text
dsCustomerIndividual - Customers.ContactTitle
Name
txtAddress
TextBox
Text
dsCustomerIndividual - Customers.Address
TextBox
Name
txtCity
Text
dsCustomerIndividual - Customers.City
TextBox
Name
txtRegion
Text
dsCustomerIndividual - Customers.Region
TextBox
Name
txtPostalCode
Text
dsCustomerIndividual - Customers.PostalCode
TextBox
Name
txtCountry
Text
dsCustomerIndividual - Customers.Country
Name
txtPhone
TextBox
TextBox
Text
dsCustomerIndividual - Customers.Phone
Name
txtFax
Text
dsCustomerIndividual - Customers.Fax
4. Теперь необходимо приступить к разработке кода. Для этого нужно, прежде всего,
откорректировать код обработчика событий Click для кнопки btnLoadList
38
Глава 1
(листинг 1.3). Первые три строки этого кода в основном совпадают со строками,
приведенными в последнем упражнении, за исключением того, что в них изменено
имя и добавлено несколько строк в качестве комментариев к коду.
Ëèñòèíã 1.3. frmHowTo1_3.vb — ââîä â ïðîãðàììó âûçîâà ïðîöåäóðû
RefreshIndividual
Private Sub btnLoadList_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles _
btnLoadList.Click
' Присвоить параметру адаптера данных значение, введенное для
' ограничения объема списка
Me.odaCustomerList.SelectCommand.Parameters(0).Value = _
Me.txtCustLimit.Text
' Удалить данные, находящиеся в настоящее время в наборе данных
Me.dsCustomerList.Clear()
' Заполнить набор данных со списком заказчиков
Me.odaCustomerList.Fill(Me.dsCustomerList)
' Заполнить отдельный набор данных, соответствующий
' начальной записи
RefreshIndividual()
End Sub
Единственная новая строка кода находится непосредственно перед оператором
End Sub (листинг 1.4); в этой строке вызывается процедура RefreshIndividual
для получения первого элемента вновь заполненного списка. В данной процедуре
вначале выполняется очистка набора данных dsCustomerIndividual. Это позво
ляет выбрать имя заказчика из списка, а затем передать выбранный элемент в каче
стве значения параметра для адаптера данных odaCustomerIndividual. После
этого заполняется набор данных dsCustomerIndividual и в текстовых полях,
связанных с этим набором данных, отображаются данные.
Ëèñòèíã 1.4. frmHowTo1_3.vb — îáíîâëåíèå íàáîðà äàííûõ, èç êîòîðîãî
ïîñòóïàþò äàííûå â òåêñòîâûå ïîëÿ
Private Sub RefreshIndividual()
' Очистить отдельные клиентские наборы данных
Me.dsCustomerIndividual.Clear()
' Определить, выбран ли элемент
If lstCustomers.SelectedIndex <> -1 Then
' Присвоить параметру адаптера данных SQL выбранный
' идентификатор заказчика
Me.odaCustomerIndividual.SelectCommand.Parameters(0).Value = _
Me.lstCustomers.SelectedItem(0)
' Заполнить набор данных
Me.odaCustomerIndividual.Fill(Me.dsCustomerIndividual)
End If
End Sub
Разработка форм Windows с использованием связанных элементов...
39
Теперь достаточно предусмотреть только код (листинг 1.5), который выполня
ется после выбора нового элемента в списке. Он обеспечивает обновление со
держимого текстовых полей и ввод в них новых данных. Этот код выполняется
при активизации события SelectedIndexChanged, которое относится к спи
ску lstCustomers.
Ëèñòèíã 1.5. frmHowTo1_3.vb — âûçîâ ïðîöåäóðû RefreshIndividual
Private Sub lstCustomers_SelectedIndexChanged(ByVal sender _
As System.Object,ByVal e As System.EventArgs) _
Handles lstCustomers.SelectedIndexChanged
' Заполнить отдельный набор данных текущего элемента списка
RefreshIndividual()
End Sub
Îïèñàíèå ïîëó÷åííûõ ðåçóëüòàòîâ
После того как пользователь вводит любую букву в текстовом поле txtCustLimit
и щелкает на кнопке btnLoadList, список заполняется элементами, соответствую
щими тексту в этом текстовом поле. После заполнения списка lstCustomers пользо
ватель видит на экране подробные сведения, относящиеся к первому элементу списка,
которые отображаются в текстовых полях. Для этого служит процедура
RefreshIndividual. Выбранный элемент используется в качестве параметра для
адаптера данных odaCustomerIndividual, после чего заполняется набор данных
dsCustomerIndividual. Если пользователь выбирает в списке другие элементы,
отображаются данные, соответствующие выбранному элементу.
Совет
Ðåêîìåíäóåòñÿ âñåãäà ðàçáèâàòü êîä ïðîãðàììû íà îòäåëüíûå ïðîöåäóðû, òàêèå êàê RefreshIndividual. Ýòî ïîçâîëÿåò óïðîñòèòü èçó÷åíèå è ñîïðîâîæäåíèå êîäà, à òàêæå èçáåæàòü îøèáîê, êîòîðûå ìîãóò âîçíèêàòü ïðè íåîäíîêðàòíîì ââîäå îäíîãî è òîãî æå êîäà â ðàçíûõ ìåñòàõ ïðîãðàììû. Ê òîìó æå,
åñëè âîçíèêíåò íåîáõîäèìîñòü îòêîððåêòèðîâàòü êîä, òî ñîîòâåòñòâóþùèå
èçìåíåíèÿ äîñòàòî÷íî áóäåò ââåñòè òîëüêî â îäíîì ìåñòå.
Êîììåíòàðèè
Способ связывания текстовых полей с наборами данных позволяет упростить ра
боту по программированию операции переключения с одной записи на другую, по
скольку не требуется каждый раз заполнять все текстовые поля данными. Такой спо
соб позволяет также упростить использование адаптеров данных и наборов данных
для корректировки данных в форме.
Как показано в следующих упражнениях, связанные наборы данных особенно удоб
ны, если требуется обеспечить редактирование, добавление и удаление данных в форме.
40
Глава 1
Óïðàæíåíèå 1.4. Ðåäàêòèðîâàíèå è
îáíîâëåíèå äàííûõ ñ èñïîëüçîâàíèåì
ñâÿçàííûõ ýëåìåíòîâ óïðàâëåíèÿ
В некоторых приложениях достаточно только обеспечить просмотр данных, но
более важными средствами программы является редактирование данных в текстовых
полях и обновление данных на сервере. В этом упражнении показаны именно эти
средства программирования с использованием некоторых новых методов и свойств
различных элементов управления данными, включая автоматическое формирование
команд, обеспечивающих создание операторов Update, Insert и Delete языка SQL.
В данном упражнении рассматривается также класс BindingContext, который ис
пользуется для проведения обновлений с помощью связанных элементов управления.
Форма, разработанная в упражнении 1.4, очень хорошо подходит для просмотра
данных различных записей. Но форма, предназначенная для редактирования и об
новления данных, должна быть организована по другому принципу.
Îáùåå îïèñàíèå
Продолжая разработку формы, которая использовалась в предыдущих упражнени
ях, введем несколько кнопок с кодом, с помощью которых можно выполнить следую
щие действия
•
Кнопка Edit. Позволяет переключаться из режима просмотра в режим редактиро
вания текстовых полей и изменять при этом их внешний вид, чтобы пользователь
знал, что он может в этих элементах управления просматривать и редактировать
или только просматривать данные; при этом изменяется форма рамок текстового
поля: в первом случае они становятся плоскими, а во втором — рельефными.
•
Кнопка Save. Обеспечивает сохранение на сервере изменений, внесенных в
данные. После записи данных в базу данных внешний вид рамок текстовых по
лей снова изменяется и они становятся плоскими, чтобы дать пользователю
знать, что данные нельзя редактировать.
•
Кнопка Cancel. Позволяет отменить режим редактирования данных; при этом
рамки текстовых полей снова становятся плоскими, чтобы пользователь мог
видеть, что данные больше нельзя редактировать и что запись откорректиро
ванных данных не была выполнена.
Очень важно, чтобы пользователи могли определить, могут ли они редактировать
данные или только просматривать их. В рассматриваемом приложении предусмотре
но использование двух стилей рамок текстовых полей (плоских и рельефных) и двух
цветов текстовых полей (серого и белого). Переходя от одного стиля отображения к
другому, можно наглядно показать пользователям, разрешено ли редактирование
данных при определенных обстоятельствах (рис. 1.8).
В этом упражнении рассматривается еще один важный компонент программы —
класс BindingContext. Этот класс упрощает работу с элементами управления, свя
занными с данными. Все элементы управления в форме Windows включают собствен
ный объект BindingContext, а также по одному объекту BindingContext для каж
Разработка форм Windows с использованием связанных элементов...
41
дого содержащегося в нем элемента управления. Объект BindingContext имеется
также в каждой форме. Объекты BindingContext управляют объектом (объектами)
класса BindingManagerBase, который относится к каждому элементу управления. В
частности, объект BindingContext позволяет управлять процессом редактирования
и обновления данных, а также передачей данных на сервер. С другой стороны, объек
ты BindingManagerBase обеспечивают синхронизацию наборов данных с элемен
тами управления. Класс BindingContext широко применяется во всех остальных уп
ражнениях данной главы, но при этом используются не все его методы.
Ðèñ. 1.8. Пример использования стиля для указания того, что
пользователь имеет возможность редактировать данные
Ïîðÿäîê äåéñòâèé
Откройте папку, в которой находится приложение VB.NET How-To - Chapter 1,
содержащее решения к упражнениям этой главы, и вызовите его на выполнение. В ос
новной форме щелкните на кнопке How-To 1.4. Затем щелкните на кнопке Load List. От
кроется форма со списком, заполненным именами заказчиков, которые начинаются с
буквы A, а в правой части формы появятся подробные сведения о первом заказчике в
списке. Щелкните на кнопке Edit. После этого вы получите возможность корректиро
вать данные в текстовых полях. Отредактировав несколько полей, щелкните на кнопке
Save. После того как вы выберете другого заказчика из списка, снова вернитесь к дан
ным о заказчике, которые вы уже корректировали. Вы сможете убедиться в том, что
внесенные вами изменения действительно записаны в базу данных. А если вместо кноп
ки Save вы щелкнете на кнопке Cancel, внесенные изменения не будут записаны. Обра
тите внимание, что если вы откорректируете название компании заказчика, то вам нуж
но будет снова загрузить список заказчиков, чтобы увидеть в списке результаты внесен
ных изменений.
1. Введите в форму три кнопки, как показано на рис. 1.8, со свойствами, значения
которых приведены в табл. 1.6.
2. Введите код, показанный в листинге 1.6, в обработчик событий Click кнопки
btnEdit.
Глава 1
42
Òàáëèöà 1.6. Êíîïêè äëÿ ðåäàêòèðîâàíèÿ, ñîõðàíåíèÿ è îòìåíû
èçìåíåíèé â äàííûõ
Объект
Свойство
Значение
Button
Name
btnEdit
Caption
&Edit
Name
btnSave
Caption
&Save
Name
btnCancel
Caption
&Cancel
Button
Button
Ëèñòèíã 1.6. frmHowTo1_4.vb — âûçîâ ïðîöåäóðû ActivateEditing
ñ ïîìîùüþ êíîïêè btnEdit
Private Sub btnEdit_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnEdit.Click
' Разрешить редактирование формы
ActivateEditing(True)
End Sub
В этом обработчике событий вызывается процедура ActivateEditing,
приведенная ниже (листинг 1.7). В представленном здесь коде выполняется
просмотр всех элементов управления в форме и используется свойство
TypeOf для определения того, является ли текущий элемент управления
текстовым полем. Предусмотрена также дополнительная проверка для кон
троля над тем, что рассматриваемый элемент управления не является тек
стовым полем txtCustLimit. Если элемент управления является тексто
вым полем и процедуре передан параметр bEnable со значением True, то
стиль рамки текстового поля изменяется на рельефный с помощью свойст
ва BorderStyle, а в качестве значения свойства цвета фона BackColor
применяется белый цвет. В ином случае свойству BorderStyle присваива
ется значение FixedSingle, которое соответствует плоскому стилю рамки,
а значение свойства BackColor становится таким же, как цвет фона фор
мы. Свойству Enabled текстового поля присваивается соответствующее
значение параметра bEnabled (True или False).
Ëèñòèíã 1.7. frmHowTo1_4.vb — ïðîöåäóðà, êîòîðàÿ ïðèìåíÿåòñÿ äëÿ
èçìåíåíèÿ çíà÷åíèÿ ñâîéñòâà Enabled è âíåøíåãî âèäà òåêñòîâûõ ïîëåé
Private Sub ActivateEditing(ByVal bEnable As Boolean)
Dim oCurr As Object
' Обработать в цикле каждый элемент управления в форме
For Each oCurr In Me.Controls()
' Определить, является ли элемент управления текстовым полем
If TypeOf oCurr Is TextBox And oCurr.Name <> "txtCustLimit" Then
Разработка форм Windows с использованием связанных элементов...
43
' В случае положительного ответа изменить значения свойств
' на противоположные
If bEnable Then
oCurr.BorderStyle() = _
System.Windows.Forms.BorderStyle.Fixed3D
oCurr.BackColor() = System.Drawing.Color.White
Else
oCurr.BorderStyle() = _
System.Windows.Forms.BorderStyle.FixedSingle
oCurr.BackColor() = Me.BackColor
End If
oCurr.Enabled = bEnable
End If
Next
End Sub
3. Введите этот код в обработчик событий Click кнопки btnSave (листинг 1.8). В
этом коде вызывается новая процедура SaveRecord, фактически обеспечи
вающая запись данных в базу данных. После записи данных вызывается проце
дура ActivateEditing, которой в качестве параметра передается значение
False, чтобы запретить корректировку данных в элементах управления, по
скольку считается, что данные записываются на диск только после завершения
редактирования.
Ëèñòèíã 1.8. frmHowTo1_4.vb — âûçîâ ïðîöåäóðû SaveRecord è îòìåíà
ðåæèìà ðåäàêòèðîâàíèÿ òåêñòîâûõ ïîëåé ïóòåì âûçîâà ïðîöåäóðû
ActivateEditing
Private Sub btnSave_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnSave.Click
' Сохранить информацию
SaveRecord()
' Отключить текстовые поля
ActivateEditing(False)
End Sub
Ниже приведен код процедуры SaveRecord (листинг 1.9). В этой процедуре вызы
вается метод EndCurrentEdit класса BindingContext; ей передается набор дан
ных dsCustomerIndividual с указанием таблицы Customers. Затем из адаптера
данных odaCustomerIndividual вызывается метод Update и ему передаются те
же параметры. В результате внесенные изменения вносятся в набор данных. И на
конец, изменения в наборе данных пересылаются обратно на сервер.
44
Глава 1
Ëèñòèíã 1.9. frmHowTo1_4.vb — ïåðåäà÷à íà ñåðâåð èçìåíèâøèõñÿ äàííûõ
Private Sub SaveRecord()
' Применить класс BindingContext для завершения текущего сеанса
' редактирования, чтобы иметь возможность записать обновленные
' данные на сервер
Me.BindingContext(Me.dsCustomerIndividual, _
"Customers").EndCurrentEdit()
' Выполнить требуемую задачу на уровне набора данных
' с использованием адаптера данных
Me.odaCustomerIndividual.Update(Me.dsCustomerIndividual, _
"Customers")
' После подтверждения изменений передать данные обратно
' на сервер
Me.dsCustomerIndividual.AcceptChanges()
End Sub
Примечание
Åñëè ÷èòàòåëü âïåðâûå çíàêîìèòñÿ ñ ðàáîòîé ñðåäû ADO.NET, òî äëÿ íåãî
ìîæåò ïîêàçàòüñÿ ñòðàííûì ïðèìåíÿåìûé ïðè ýòîì ïîäõîä: îáíîâëåíèå íàáîðà äàííûõ, ïîäòâåðæäåíèå âíåñåííûõ èçìåíåíèé, à çàòåì ïåðåäà÷à ýòèõ
èçìåíåíèé îáðàòíî íà ñåðâåð. Íî äåëî â òîì, ÷òî ôóíêöèîíèðîâàíèå ñðåäû
ADO.NET îñíîâàíî íà èñïîëüçîâàíèè ðàçúåäèíåííûõ íàáîðîâ äàííûõ. Ïðè
ñîçäàíèè íàáîðà äàííûõ ñ èñïîëüçîâàíèåì àäàïòåðà äàííûõ ôàêòè÷åñêè
ôîðìèðóåòñÿ ôàéë â êîäå XML. ×òîáû óáåäèòüñÿ â ýòîì, ðàññìîòðèòå ôàéë
dsCustomerIndividual.xsd, êîòîðûé ìîæíî íàéòè â êàòàëîãå ïðîãðàììû
Solutions Explorer.
<xsd:schemaid="dsCustomerIndividual"targetNamespace="http://www.tem
puri.org/dsCustomerIndividual.xsd"xmlns="http://www.tempuri.org/dsC
ustomerIndividual.xsd"xmlns:xsd="http://www.w3.org/2001/XMLSchema
"xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"
attributeFormDefault="qualified"elementFormDefault="qualified">
<xsd:element name="dsCustomerIndividual" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="Customers">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="CustomerID" type="xsd:string" />
<xsd:element name="CompanyName" type="xsd:string" />
<xsd:element name="ContactName" type="xsd:string"
minOccurs ="0" />
<xsd:element name="ContactTitle" type="xsd:string"
minOccurs ="0" />
<xsd:element name="Address" type="xsd:string" minOccurs= "0" />
<xsd:element name="City" type="xsd:string" minOccurs="0" />
<xsd:element name="Region" type="xsd:string" minOccurs = "0" />
<xsd:element name="PostalCode" type="xsd:string"
minOccurs = "0" />
<xsd:element name="Country" type="xsd:string" minOccurs= "0" />
<xsd:element name="Phone" type="xsd:string" minOccurs="0" />
<xsd:element name="Fax" type="xsd:string" minOccurs="0" />
Разработка форм Windows с использованием связанных элементов...
45
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
<xsd:unique name="Constraint1" msdata:PrimaryKey="true">
<xsd:selector xpath=".//Customers" />
<xsd:field xpath="CustomerID" />
</xsd:unique>
</xsd:element>
</xsd:schema>
Âñå ýòè äåéñòâèÿ âûïîëíÿþòñÿ íåçàìåòíî äëÿ ïîëüçîâàòåëÿ, ïîýòîìó äëÿ ðàáîòû ñ íàáîðàìè äàííûõ è ñðåäîé ADO äàæå íå ïðèõîäèòñÿ èçó÷àòü ÿçûê XML. Äîïîëíèòåëüíàÿ èíôîðìàöèÿ ïî ýòîé òåìå ïðèâåäåíà â ãëàâå 3, “Ïðîñìîòð
äàííûõ ñ ïðèìåíåíèåì ñðåäñòâ ADO.NET”.
4. Последнее задание этого упражнения состоит в реализации возможности от
мены редактирования. Для этого достаточно поместить следующий код в обра
ботчик событий Click кнопки btnCancel (листинг 1.10). Текущие результаты
редактирования отменяются с использованием метода CancelCurrentEdit
объекта BindingContext данной формы. После этого происходит отмена ре
жима
редактирования
текстовых
полей
с
помощью
процедуры
ActivateEditing.
Ëèñòèíã 1.10. frmHowTo1_4.vb — îòìåíà èçìåíåíèé, âíåñåííûõ â äàííûå,
è ïîâòîðíîå çàïðåùåíèå ðåäàêòèðîâàíèÿ òåêñòîâûõ ïîëåé
Private Sub btnCancel_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles _
btnCancel.Click
' Для отмены текущей операции редактирования применяется
' класс BindingContext
Me.BindingContext(Me.dsCustomerIndividual, _
"Customers").CancelCurrentEdit()
ActivateEditing(False)
End Sub
Îïèñàíèå ïîëó÷åííûõ ðåçóëüòàòîâ
После того как пользователь щелкнет на кнопке btnEdit, процедура
ActivateEditing показывает, что он может редактировать данные в текстовых по
лях. Текстовые поля переводятся в режим редактирования.
Если пользователь после этого щелкнет на кнопке btnSave, то откорректиро
ванные им данные вводятся в набор данных, а затем передаются на сервер для их
сохранения. Если же пользователь щелкнет на кнопке btnCancel, то внесенные им
изменения отменяются. В обоих случаях вызывается процедура ActivateEditing,
которая отменяет режим редактирования текстовых полей и, изменив стиль ото
бражения текстовых полей, показывает пользователю, что текстовые поля больше
нельзя редактировать.
46
Глава 1
Êîììåíòàðèè
В этом упражнении рассматриваются основные функции редактирования и обнов
ления данных. Здесь представлены наиболее важные операции, с которых начинает
ся разработка реальных программ. А в следующих упражнениях показаны способы
добавления и удаления записей, а также обработки ошибок.
Способы применения связанных элементов управления в среде ADO.NET немного
напоминают способы доступа к данным, которые используются в таких технологиях,
как ADO и DAO. Но объекты BindingContext и BindingManagerBase намного уп
рощают работу со связанными объектами в приложениях.
Óïðàæíåíèå 1.5. Äîáàâëåíèå
è óäàëåíèå çàïèñåé ñ èñïîëüçîâàíèåì
ñâÿçàííûõ ýëåìåíòîâ óïðàâëåíèÿ
Не менее важной задачей, чем редактирование данных, является добавление но
вых и удаление существующих записей в таблице. В этом упражнении показано, как
выполнить эту задачу с помощью класса BindingContext.
Пользователи должны иметь возможность не только редактировать существующие
записи, но также добавлять и удалять записи. Ниже описаны способы добавления и
удаления записей с помощью связанных элементов управления.
Îáùåå îïèñàíèå
Чтобы ввести в программу средство добавления новой записи Add New Record,
разместим на форме новую кнопку btnAddNew и добавим в программу соответст
вующий код. Для ввода новой записи с помощью метода AddNew снова используется
объект BindingContext. В форме применяется переменная уровня модуля для
контроля над тем, происходит ли добавление или редактирование записи. Если
вводится новая запись, то при обновлении данных в приложении необходимо пере
загрузить данные в списке в том случае, если значение поля CompanyName новой
записи соответствует области охвата списка, который определен согласно содер
жимому текстового поля txtCustLimit.
С другой стороны, чтобы ввести в приложение средство удаления записи Delete
Record, на форме размещена кнопка btnDelete. Код, который обеспечивает функ
ционирование этой кнопки, включает метод RemoveAt объекта BindingContext,
используемый для удаления записи из набора данных. Затем откорректированные
данные снова возвращаются на сервер.
Ïîðÿäîê äåéñòâèé
Откройте папку, в которой находится приложение VB.NET How-To - Chapter 1,
содержащее решения к упражнениям этой главы, и вызовите его на выполнение. В ос
новной форме щелкните на кнопке How-To 1.5. Щелкните на кнопке Load List, а затем
на кнопке New. Введите текст ALF в поле Customer ID и Alfred's Fried Foods в поле
Company Name. После этого щелкните на кнопке Save и проследите за тем, как проис
Разработка форм Windows с использованием связанных элементов...
47
ходит добавление к списку только что введенной записи. После ввода записи можно
проверить средства удаления, щелкнув на кнопке Delete. Запись исчезнет, и на экране
появится откорректированный список.
1. Под кнопкой btnEdit поместите новую кнопку, а затем укажите в качестве свойст
ва Name этой кнопки значение btnNew, а в качестве свойства Caption — &Save.
2. Введите новую переменную уровня модуля mbAddNew, которая представляет
собой логическую переменную, применяемую для контроля над тем, происхо
дит ли добавление новой записи. Код объявления этой переменной будет нахо
диться за пределами кода всех процедур, непосредственно вслед за кодом
форм, как показано на рис. 1.9.
Ðèñ. 1.9. Пример размещения переменной под кодом, сгенерированным програм#
мой проектирования форм Windows, и ее объявления с атрибутом Private, что
позволяет обеспечить к ней доступ из процедур класса, а не из внешних процедур
Совет
Ïðåäóñìîòðåíà âîçìîæíîñòü ñâåðòûâàòü è ðàçâåðòûâàòü êîä ïðîöåäóð, âõîäÿùèõ â ñîñòàâ ðàçðàáàòûâàåìûõ ìîäóëåé, â îêíå ïðîãðàììû ïðîåêòèðîâàíèÿ
ôîðì. Ýòî ïîçâîëÿåò óïðîñòèòü ðàáîòó ïðè ñîçäàíèè íîâûõ ïðîöåäóð (êîä êîòîðûõ ìîæåò áûòü ðàçâåðíóò íà ýêðàíå) è èñêëþ÷èòü íåîáõîäèìîñòü âèäåòü ïîëíûé
òåêñò ñóùåñòâóþùèõ ïðîöåäóð (êîòîðûé ìîæåò áûòü âåñüìà ïðîñòðàííûì).
3. Введите следующий код в обработчик событий Click новой кнопки btnNew
(листинг 1.11). В этом коде прежде всего логической переменной mbAddNew
присваивается значение True. Затем в нем используется метод AddNew объекта
48
Глава 1
BindingContext формы для добавления новой записи к набору данных
dsCustomerIndividual. И наконец, в этом коде вызывается процедура
ActivateEditing для перехода в режим редактирования текстовых полей.
Ëèñòèíã 1.11. frmHowTo1_5.vb — äîáàâëåíèå íîâîé çàïèñè ê íàáîðó äàííûõ
dsCustomerIndividual è ñìåíà ðåæèìà ðåäàêòèðîâàíèÿ òåêñòîâûõ ïîëåé
Private Sub btnNew_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnNew.Click
mbAddNew = True
' Добавить новую запись с использованием класса BindingContext
Me.BindingContext(Me.dsCustomerIndividual, "Customers").AddNew()
ActivateEditing(True)
End Sub
4. Откорректируйте код обработчика событий Click кнопки btnSave и преду
смотрите в нем проверку того, присвоено ли флажку mbAddNew значение True,
что означает добавление новой записи (листинг 1.12). Если флажок имеет зна
чение True, то после сохранения записи путем вызова процедур SaveRecord и
ActivateEditing вызываются процедуры LoadList и RefreshIndividual
для загрузки данных новой записи. Обратите внимание, что код процедур
SaveRecord, ActivateEditing и RefreshIndividual не изменился по
сравнению с упражнением 1.4. После этого переменной mbAddNew присваива
ется значение False.
Ëèñòèíã 1.12. frmHowTo1_5.vb — ñîõðàíåíèå èçìåíèâøèõñÿ äàííûõ, ñìåíà
ðåæèìà ðåäàêòèðîâàíèÿ òåêñòîâûõ ïîëåé, à òàêæå ïåðåçàãðóçêà ñïèñêà
è ïåðâîé çàïèñè â ñïèñêå
Private Sub btnSave_Click(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles btnSave.Click
' Сохранить информацию
SaveRecord()
' Отключить текстовые поля
ActivateEditing(False)
If mbAddNew Then
LoadList()
RefreshIndividual()
mbAddNew = False
End If
End Sub
5. Откорректируйте код обработчика событий Click кнопки btnCancel, чтобы в
нем переменной mbAddNew присваивалось значение False, как показано в лис
тинге 1.13.
Разработка форм Windows с использованием связанных элементов...
49
Ëèñòèíã 1.13. frmHowTo1_5.vb — îòìåíà ðåæèìà ðåäàêòèðîâàíèÿ
è èçìåíåíèå çíà÷åíèÿ ïåðåìåííîé mbAddNew
Private Sub btnCancel_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnCancel.Click
' Для отмены текущей операции редактирования применяется
' класс BindingContext
Me.BindingContext(Me.dsCustomerIndividual, _
"Customers").CancelCurrentEdit()
ActivateEditing(False)
mbAddNew = False
End Sub
6. Теперь можно приступить к разработке функциональных средств удаления
записей. Для этого введите следующий код в обработчик событий Click но
вой кнопки, обозначенной как btnDelete (листинг 1.14). Первая строка
вновь введенного кода начинается с оператора вызова нового метода
RemoveAt и нового свойства Position, которые используются с объектом
BindingContext. Выполнение компонентов этого оператора происходит,
начиная от внутренних и заканчивая внешними программными конструк
циями. Свойство Position применяется для отслеживания позиции текущей
записи в наборе данных, в рассматриваемом случае dsCustomerIndividual.
Метод RemoveAt позволяет отметить запись, находящуюся в определенной
позиции, как подлежащую удалению.
Затем используется метод Update адаптера данных odaCustomerIndividual
для вызова оператора DELETE языка SQL применительно к рассматриваемому
набору данных и фактического удаления строк из набора данных. Для передачи
на сервер информации об изменениях, внесенных в набор данных (в этом слу
чае — об удалении записи), применяется метод AcceptChanges. И наконец,
вызываются процедуры LoadList, RefreshIndividual и ActivateEditing
для обновления списка, выборки новых данных из первой записи в списке и
отображения этих данных в текстовых полях, а также переключения текстовых
полей в режим просмотра, чтобы дать пользователю понять, что эти данные
нельзя редактировать.
Ëèñòèíã 1.14. frmHowTo1_5.vb — óäàëåíèå âûáðàííîé çàïèñè
è ïåðåçàãðóçêà ñïèñêà
Private Sub btnDelete_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles _
btnDelete.Click
' Отметить строку для удаления с использованием
' метода RemoveAt объекта BindingContext
Me.BindingContext(Me.dsCustomerIndividual, _
"Customers").RemoveAt(Me.BindingContext(Me.dsCustomerIndividual, _
"Customers").Position)
' Выполнить требуемую задачу на уровне набора данных
' с использованием адаптера данных
50
Глава 1
odaCustomerIndividual.Update(dsCustomerIndividual, "Customers")
' После подтверждения изменений передать данные обратно
' на сервер
dsCustomerIndividual.AcceptChanges()
' Перезагрузить список
LoadList()
' Отобразить первую запись
RefreshIndividual()
' Отключить текстовые поля
ActivateEditing(False)
End Sub
Îïèñàíèå ïîëó÷åííûõ ðåçóëüòàòîâ
После того как пользователь щелкнет на кнопке btnNew, флажку mbAddNew при
сваивается значение True, набор данных подготавливается для добавления записи с
помощью метода AddNew объекта BindingContext, а текстовые поля переводятся в
режим редактирования.
Если пользователь после этого щелкнет на кнопке btnSave, то откорректирован
ные им данные вводятся в набор данных, а затем передаются на сервер для сохране
ния. Если же пользователь щелкнет на кнопке btnCancel, то внесенные изменения
отменяются. В обоих случаях переменной mbAddNew присваивается значение False и
вызывается процедура ActivateEditing, которая отменяет режим редактирования
и изменяет стиль отображения текстовых полей, чтобы дать пользователю знать, что
текстовые поля недоступны для редактирования. И наконец, если сделан щелчок на
кнопке btnSave, а переменной mbAddNew присвоено значение True, то вызываются
процедуры LoadList и RefreshIndividual.
После того как пользователь щелкнет на кнопке btnDelete, запись удаляется из
набора записей, а затем из базы данных на сервере. Перезагружается список, и в тек
стовых полях отображаются данные первой записи в списке. После этого отменяется
режим редактирования текстовых полей.
Êîììåíòàðèè
В этом упражнении показаны основные программные конструкции, необходимые для
создания полнофункциональной формы ввода данных. С помощью этой формы пользова
тель имеет возможность добавлять, редактировать и удалять записи. Для этого фактически
требуется меньший объем кода, чем при использовании языка Visual Basic 6.0.
Вполне очевидно, что объект BindingContext позволяет выполнить значитель
ную часть работы по обработке связанных данных.
Разработка форм Windows с использованием связанных элементов...
51
Óïðàæíåíèå 1.6. Îáðàáîòêà îøèáîê
ñ ïîìîùüþ ñâÿçàííûõ ýëåìåíòîâ
óïðàâëåíèÿ
В процессе эксплуатации приложений и баз данных иногда приходится сталки
ваться с ошибками времени выполнения. В среде .NET всевозможные возникающие
при этом ошибки принято называть исключениями. В настоящем упражнении приведе
ны примеры ситуаций, при которых могут возникать исключения, и показаны спосо
бы обработки исключений с помощью операторов Try, Catch и Finally.
Возможность добавления и удаления записей в программе является очень важной,
но необходимо также предусмотреть выполнение определенных действий при воз
никновении ошибок. Ниже приведен пример окна с сообщением, которое появилось
при попытке удалить данные о существующей компании (рис. 1.10).
Ðèñ. 1.10. Сообщение о необработанной
ошибке, которое в среде .NET называется ис#
ключением
Ниже описаны способы корректной обработки ошибок в приложении, в котором
используются связанные элементы управления.
Îáùåå îïèñàíèå
Обработка ошибок, которые обычно возникают в процессе ввода данных пользовате
лем и обновления базы данных на сервере, является одной из наиболее важных состав
ляющих работы с данными. Если в программе не предусмотрено применение соответст
вующих средств обработки ошибок, то в лучшем случае система выводит сообщение об
ошибке, которое с трудом поддается расшифровке, а в худшем — аварийно завершает свою
работу или записывает в базу данных ошибочные данные. В среде Visual Studio .NET для
обработки ошибок применяются классы, называемые исключениями. В иерархию исключе
ний входит большое число различных (в основном унаследованных) типов исключений.
Исключения времени выполнения могут возникать почти в любой части приложе
ния. В программе может быть предусмотрена обработка этих исключений с помощью
конструкций Try...Catch...Finally или эти исключения могут остаться необра
ботанными, и тогда на экране отображается сообщение об ошибке, аналогичное при
веденному на рис. 1.10.
В листинге 1.15 показан общепринятый способ перехвата исключений.
Глава 1
52
Ëèñòèíã 1.15. Ñòàíäàðòíûé êîä îáðàáîòêè èñêëþ÷åíèé
Private Sub MySub()
Try
' Здесь находится код, в котором могут активизироваться
' исключения
Catch dataException as Exception
MessageBox.Show(dataException.Message)
Finally
' Код, выполняемый независимо от того, возникла ошибка
' или нет
End Try
End Sub
Ниже перечислены некоторые основные сведения, которыми следует руководство
ваться при работе с исключениями и использовании блоков Try...Catch...Finally.
•
Для объекта исключения может быть выбрано любое имя. Имя dataException
было взято лишь в качестве примера.
•
Конкретные типы исключений происходят от базового класса System.Exception.
Одним из таких производных классов является OleDbException, и примеры его
применения будут показаны в данном упражнении.
•
В блочном операторе Catch может находиться оператор Throw, который по
зволяет вновь активизировать это же исключение, после чего оно передается в
вызывающую процедуру.
•
Для перехвата конкретных исключений может использоваться конструкция
When оператора Catch.
•
При использовании нескольких операторов Catch выполняется каждый из
них, если в блок Catch не включен оператор End Try или End Sub, как в дан
ном упражнении.
•
В программе может быть предусмотрено несколько операторов Catch для об
работки всех возможных исключений, которые могут в ней возникнуть.
В данном упражнении показано, как эти рекомендации применяются на практике.
Ïîðÿäîê äåéñòâèé
В этом упражнении взята за основу разработанная форма, в которую введен код
обработки исключений, возникающих при сохранении записи в базе данных (после
ее добавления или корректировки) и при удалении записи. Здесь предусмотрено так
же применение кода обработки события, возникающего при закрытии формы.
1. Откорректируйте
код обработчика событий Click кнопки btnSave
(листинг 1.16). Для этого необходимо заключить вызов процедуры SaveRecord
в блок Try...Catch...End Try. Если возникает исключение, то вызывается
метод Show класса MessageBox и ему передается свойство Message объекта
Download