2. Работа с наборами типизированных данных

Представление табличных данных в сетке

когда заказчик выбран сверху на

В качестве простого примера предположим, что вы хотите представить на странице таблицу заказчиков, чтобы можно было выбрать заказчика из списка. Когда заказчик выбран, сверху на странице должно отображаться название его компании. Реализующий данную задачу код показан в листингах А.1 и А.2. Запущенное приложение показано на рис. А.1 . Web-форма ASP. NET всегда содержит код HTML, в соответствии со стандартом HTML для Web-страниц размечающий элементы заголовка и тела. Каждая Web-форма должна иметь единственный элемент формы, который содержит всю специфическую разметку ASP. NET. Внутри этого элемента формы другие теги разметки определяют элементы управления, из которых составляется страница, а также атрибуты или дочерние элементы этих тегов, которые управляют их поведением при отображении в браузере. Теги разметки могут перемежаться со встроенным сценарием любого объема в различных формах блоков сценария. Из кода в листинге А.1 видно, что здесь объявляются три элемента управления ASP. NET — две метки Label И сетка DataGrid. Каждый тег снабжен префиксом asp:, привязывающий имя тега к именному пространству, в котором определяются элементы управления Web-сервера. Каждый из них имеет также атрибуты Id И Runat="Server". Атрибут Id Используется для соотнесения тега с элементом управления во время исполнения, a Runat Идентифицирует элемент управления как серверный, экземпляр которого будет создаваться и вызываться во время обработки страницы на сервере. Сложные элементы управления, подобные DataGrid, Имеют усложненную схему допустимых дочерних атрибутов и элементов, которые позволяют настроить их поведение при отображении во время исполнения. Значения любых свойств, которые экспонируются классом элемента управления как открытые или закрытые, могут также устанавливаться в разметке посредством спецификации этих свойств в качестве атрибутов тега разметки данного элемента управления. В элементе DataGrid В листинге А.1 в качестве дочернего элемента коллекции Columns Специфицируется единственный элемент управления столбца типа ButtonColumn. Дополнительные колонки здесь будут добавляться динамически, когда сетка будет привязываться к данным.

Интерфейсы привязки данных

в этой главе описываются ключевые

Чтобы действительно понимать, как работает привязка данных и как реализуются специальные источники данных или специальные элементы управления с привязкой к данным, нужно прежде всего понять контракты интерфейсов, приводящих привязку данных в действие. В этой главе описываются ключевые интерфейсы, имеющие отношение к привязке данных, с точки зрения контракта, представляемого каждым из интерфейсов. Здесь обсуждается назначение каждого интерфейса, когда он используется и что он определяет. В этой главе меньше практических примеров, чем в большинстве других глав, но она должна ближе познакомить вас с интерфейсами и послужить справочным руководством по их использованию и реализации. Возможно, при чтении этой главы лучше всего будет сначала просмотреть все ее разделы, уделяя внимание той их части, где описывается назначение и применение каждого интерфейса. После этого, если вы захотите побольше узнать о конкретном интерфейсе, прочитайте подробности о его элементах и реализации. Некоторая взаимозависимость интерфейсов неизбежна, поэтому в некоторых случаях мне приходится говорить об отношении данного интерфейса к другому интерфейсу, который пока еще не описывался. В таком случае не бойтесь заглянуть вперед и прочитайте сводку по этому другому интерфейсу, чтобы составить о нем представление, и возвращайтесь назад к тому, который вы в данный момент изучаете.

Событие CellFormatting

если вы хотите модифицировать действительное

Событие CellFormatting Запускается для каждой ячейки при ее отображении, что позволяет исследовать и, возможно, модифицировать значение, которое будет представлено в любой из ячеек сетки. Если вы хотите модифицировать действительное значение несвязанного столбца, которое сохраняется в коллекции ячеек сетки, используйте событие RowsAdded, Позволяющее установить сразу все значения несвязанных столбцов при добавлении строки, не обрабатывая события, запускаемые для каждой ячейки по отдельности. Если данные, которые вы представляете, являются исключительно вычисляемыми, а не извлекаются или выводятся из привязанных данных, следует рассмотреть возможность использования виртуального режима для заполнения этих ячеек, что будет рассмотрено в следующем разделе. Генерируйте вычисляемые столбцы там, где это имеет смысл Пример, представленный в этом разделе, просто генерировал новый столбец из содержания других столбцов. Если бы это требовалось делать исключительно в целях отображения, то использование несвязанного столбца могло быть наилучшим решением. Однако если содержимое этого столбца потребовалось бы в другом месте приложения, разумнее было бы включить его в состав данных вашего приложения, сделав специальным столбцом данных, который определяется выражением в самом наборе данных. Добавить к таблице типизированного набора данных специальный столбец довольно просто, если использовать конструктор наборов данных, причем имеется ряд специальных выражений для определения значений такого столбца по другим данным таблицы. Если вам требуется генерировать данные столбца, исходя из данных других таблиц в базе данных, будет еще разумнее сделать это в сохраняемой процедуре. Суть вышесказанного в том, что для вычисляемых данных следует выбирать подходящее место. Не используйте несвязанные столбцы в многократно повторяемом коде, чтобы отображать нечто такое, что можно было вы вычислить единственный раз и сделать действительным компонентом данных, с которыми вы работаете.

Верификация вверх по иерархии элементов управления

в случае типичной формы в

Класс ContainerControl Определяет метод Validate, Который верифицирует текущий элемент управления, обладающий фокусом, а затем пойдет вверх по иерархии элементов управления, верифицируя каждого из его предков. В случае типичной формы в стиле диалога каждый элемент управления является дочерним элементом формы, так что единственным предком каждого элемента управления будет сама форма. Сам по себе класс Form Ничего не делает в ответ на верификацию, поскольку непосредственно не содержит вводимых данных. Но если форма содержит другие контейнерные элементы управления, такие, как пользовательские элементы управления или расслоенные контейнеры, то непосредственным предком любого элемента управления, содержащегося в контейнере, будет этот контейнер, а предком контейнера будет форма. Метод Validate Часто использовался в приложениях. NET 1.1 для программной проверки того, что все элементы управления на форме находятся в действительном состоянии. Однако поскольку Validate Проверяет только текущий элемент управления в фокусе и его предков, для проверки нужно было итерировать по всем элементам управления в коллекции Controls Формы, устанавливая фокус на каждый из них и вызывая затем Validate. Такая методика была утомительной и проблематичной, поэтому требовался какой-то лучший подход. Вы как прежде можете вызывать Validate Для формы или элемента управления в фокусе, чтобы программно активировать верификацию, но обычно вы скорее всего предпочтете воспользоваться новым методом ValidateChildren.

Метод Validate Возвращает True, Если верификация успешна, что опять же определяется тем, устанавливает ли элемент управления в фокусе свойство Cancel Аргумента события в true. Если элемент управления в фокусе или любой элемент управления выше в иерархии говорит «нет», устанавливая свойство Cancel, То метод Validate Возвращает False, И ваш код должен принять соответствующие меры для оповещения пользователей о проблеме, и обычно вы захотите предотвратить продолжение работы, пока ошибка не будет исправлена.

Экземпляр строки данных

вы можете инкапсулировать расположение и

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

Чтобы работать с нижележащими данными более свободно, вы можете обращаться к данным косвенно через источник привязки, при этом не будет необходимости в приведении к конкретному типу во время разработки. В классе BindingSource Имеется индексатор, так что вы можете передать индекс для доступа к определенному элементу и получить ссылку на объект: Вы можете обратиться к свойству List, Которое вернет вам ссылку типа IList. Затем вы можете просмотреть элементы коллекции последовательно или индексируя ее через ссылку на IList. Получив ссылку на объект любым из этих способов, вы можете воспользоваться дескрипторами свойств, чтобы получить информацию об объектах, обслуживаемых источником привязки, не зная их типов на этапе проектирования. Вы также можете использовать источник привязки, не привязывая его к конкретному источнику данных. Если для экземпляра источника привязки не был установлен источник данных, вы можете добавлять объекты непосредственно в список, поддерживаемый источником привязки. Для этого можно использовать методы Add И AddNew Класса BindingSource. Метод Add Вставляет элемент в поддерживаемый список. Если в список еще ничего не добавлялось , То первый добавленный элемент определит и тип объектов в List, Поддерживаемом источником привязки. Последующие попытки добавления элементов в список должны передавать объекты того же типа, в противном случае будет выброшено исключение InvalidOperationEx — Ception, Поскольку элементы в списке должны быть однотипными. Установка свойства DataSource Переустанавливает всю коллекцию любой новой коллекцией данных, на которую указывает новое значение свойства, что приводит к потере всех элементов, добавленных вручную при помощи метода Add.