3. Общее представление о привязке данных в Windows Forms

Набор данных для выполнения обновлений через адаптер данных

как упоминалось выше объекты b

Когда вы используете набор данных для выполнения обновлений через адаптер данных, вы должны предусмотреть также отображение столбца в таблице на параметр, которому он будет передаваться. Как упоминалось выше, объекты SqlParameter Могут быть инициализированы посредством свойств, экспонируемых классом, но в этом примере используется один из перегруженных конструкторов, который принимает все необходимые значения в одной строке кода. Имя столбца, которое вы специфицируете для последнего параметра, позволяет адаптеру данных автоматически извлечь текущее значение столбца для каждой строки и установить его в качестве значения параметра в момент, когда происходит обновление. Если имеет место какое-либо несоответствие типов между значением в таблице и типом параметра, этого нельзя узнать до времени исполнения. Точно так же, как может выбрасывать исключения запрос, может выбрасывать исключения и код установки, предшествующий запросу. Вам нужно убедиться, что любые методы доступа к данным или код, который их вызывает, охвачены соответствующим кодом обработки исключений, если вы не хотите, чтобы выше приложение потерпело крах Если вы работаете с сохраняемыми процедурами, имеющими выходные параметры, такими, как показанная ранее процедура INSERT, которая возвращала значение столбца идентификации, вам нужно будет специфицировать направление параметра, когда вы добавляете его к объекту команды: Тем самым столбец ID в таблице данных будет отображен на выходной параметр @ID сохраняемой процедуры. После того как адаптер данных вызовет InsertCommand Для выполнения вставки, он возьмет значение, находящееся в IdParam После завершения команды, и поместит его в соответствующий столбец таблицы данных.

Каскадирование источников привязки для привязки вида ведущий-детализация

в подобном случае вам потребуется

Сценарии простой привязки данных встречаются весьма часто, но нередки и ситуации, когда на одной форме необходимо отображать несколько взаимосвязанных наборов данных. В подобном случае вам потребуется обеспечить синхронизацию этих наборов данных в смысле того, какая запись в каждом из наборов будет являться текущей. Например, взгляните на схему данных, изображенную на рис. 4.2. В ней имеется несколько таблиц, связанных родительско-дочерними отношениями, которые передаются сквозь несколько поколений, или уровней данных. Как вы видели в главе 3, привязка «ведущий-детализация» легко реализуется при помощи источников привязки. Нужно соединить последовательно два источника привязки так, чтобы один источник был привязан к родительскому источнику данных, а дочерний источник — к родительскому источнику привязки. Затем вы устанавливаете в свойстве DataMember Дочернего источника имя того свойства в родительских объектах, которое представляет соответствующую дочернюю коллекцию данных. В случае набора данных это свойство будет на самом деле именем отношения, связывающего родительскую и дочернюю таблицы. Наконец, вы привязываете соответствующие элементы управления к родительскому и дочернему источникам привязки. После этого дочерний источник привязки будет автоматически управлять фильтрацией данных, отображаемых в дочерних элементах управления в зависимости от текущего элемента в родительском источнике данных. Эта схема работает вне зависимости от того, что представляют собой родительский и дочерний источники данных, — таблицы или коллекции объектов.

Привязка к источникам данных существующих элементов управления

однако в вашу группу разработчиков

Использование окна Data Sources для генерации привязанных элементов управления — это простой способ создать форму и предоставить конструктору написать за вас код привязки данных. Однако в вашу группу разработчиков, возможно, входят дизайнеры пользовательских интерфейсов, которые проектируют формы и ничего не знают о привязке данных, и программисты, которые будут писать код, обеспечивающий работоспособность форм. Возможно, вы сами предпочитаете сначала проектировать пользовательский интерфейс, планировать расположение элементов управления, именовать их и т. д., а затем уже привязывать их к данным. Возможна также ситуация, когда уровень доступа к данным и рабочий уровень разрабатываются параллельно, и определения типов, необходимые для генерации элементов управления, на данный момент еще недоступны. Так или иначе, окно Data Sources позволяет генерировать код привязки данных для элементов управления, уже существующих на форме. Воспользоваться этой возможностью нетрудно. Если у вас на форме есть существующий элемент управления, например, текстовое поле или сетка, вы можете перетащить элемент из окна Data Sources на этот элемент управления. Если тип перетаскиваемого элемента совместим по типу со свойством привязываемого элемента управления, конструктор автоматически генерирует код, привязывающий свойство привязки по умолчанию элемента управления к элементу данных. Все происходит точно так же, как в случае, когда конструктор создает новый элемент управления, только используется уже существующий элемент. При этом конструктор генерирует все необходимые компоненты, включая источник привязки, навигатор, а также набор данных и адаптер таблицы, если перетаскиваемый элемент является таблицей данных. Когда вы перетаскиваете элемент из окна Data Sources на форму, вид указателя мыши меняется, подсказывая, что получится в результате отпускания элемента. Если элемент из окна Data Sources перетаскивается на свободное место формы, указатель мыши показывает маленький плюс, сигнализируя о добавлении элемента на форму.

Установка источника данных в окне Properties

однако то что представлено в

Редактор свойств позволяет просматривать источники данных проекта примерно таким же образом, как вы это делали в окне Data Sources. Однако то, что представлено в дереве источников данных, соответствует свойству, которое вы настраиваете, и определяется тем, какие совместимые с ним компоненты данных имеются в источнике. Например, на рис. 5.16 показана установка свойства Datasource Элемента управления ComboBox, Который предназначен для отображения только списочных источников данных. Таким образом, дерево отражает только элементы, которые реализуют надлежащий интерфейс IList Для привязки к данному свойству. Заметьте, что сюда также относятся отношения внешних ключей для связанных таблиц в наборе данных, а также дочерние коллекции других объектов данных. Вы даже можете, при помощи мастера Data Source Configuration, прямо из ссылки на связанный элемент управления в нижней части всплывающего окна редактора создать новый набор данных. Текущий выбор в других свойствах привязки будет ограничивать то, что предоставляется для установки конкретного привязываемого свойства. Например, как видно из рис. 5.17, для свойства DisplayMember Отображаются только отдельные столбцы или свойства списочного источника, выбранного для свойства Datasource Данного элемента управления.

Когда вы выбираете элементы в дереве источника данных, конструктор выполняет действия, сходные с теми, что производятся при перетаскивании элементов из окна Data Sources на форму. А именно, для этого источника данных создается источник привязки, если он не был создан ранее. Если источником является типизированный набор данных, конструктор создает экземпляр набора данных в качестве элемента формы, а также адаптер таблицы для заполнения набора данными. Если на форме уже есть подходящий источник привязки, он отображается в дереве источников данных, и вы можете выбрать источник привязки в качестве источника данных, чтобы не создавать второй источник привязки для этой формы.

Еще одно псевдосвойство, полезное для настройки привязки данных, это псевдосвойство.

Интерфейсы lEnumerable и lEnumerator

net поддержка для них предусмотрена

Поскольку интерфейсы LEnumerable И LEnumerator Образуют фундаментальную модель. NET, поддержка для них предусмотрена на уровне языка. Как в С#, так и в VB. NET имеется конструкция Foreach, Позволяющая осуществить итерацию по коллекции совсем просто: За операцией Foreach Скрыта описанная выше итерация по коллекции, использующая свойство Current И метод MoveNext Из интерфейса LEnumerator Объекта, который возвращается методом GetEnumerator. Генерируемый код на промежуточном языке IL на самом деле не использует для доступа к текущему элементу ссылку на интерфейс LEnumerator; Он просто обращается к свойству Current Самого объекта. Поэтому, если реализующий интерфейс LEnumerator Тип содержит свойство

Current, Возвращающее экземпляр конкретного типа , Цикл Foreach Может избежать упаковки и распаковки этих значений при итерации по коллекции. Подробности того, почему Foreach Реализуется подобным образом, приводятся ниже в рубрике «Проблема с небезопасным по типу перечислением». При реализации в. NET 2.0 коллекций, которые будут содержать конкретные типы, вы должны реализовать также обобщенные версии этих интерфейсов, LEnumerable<T> И IEnumerator<T>. Обобщенные типы интерфейсов используются в. NET 2.0 для обеспечения типовой безопасности для содержащихся в коллекции типов, а также чтобы избежать издержек производительности, которые могут возникать при использовании интерфейсов LEnumerable И LEnumerator В коллекциях, содержащих типы-значения. Для нетипизированных интерфейсов все равно остается место; они используются в. NET привязанными элементами управления, поскольку последние не должны делать предположений о конкретных типах в коллекциях, которые вы собираетесь привязывать, так как это ограничило бы их возможные сценарии привязки. В интерфейс LEnumerator<T> Не включен метод Reset, Чтобы упростить реализацию объектов-перечислителей. Для простых коллекций, где используется непосредственная индексация массива объектов, сброс перечислителя не представляет проблемы. Но в более сложных сценариях реализация метода Reset Может стать непростой задачей, не стоящей затраченных усилий.