4. Привязка объектов контроля к источникам данных

Приложение Hello World

для этого вам потребуется создать

Давайте начнем с простого приложения WinFx «Hello World», не используя ничего, кроме кода. Для этого вам потребуется создать проект в Visual Studio 2005. Имеются типы проектов WinFx, которые добавляются в Visual Studio 2005 Beta 2 при установке Visual Studio Extensions for WinFx, так что вам нужно будет установить эти расширения, равно как и компоненты среды выполнения вместе с WinFx SDK.

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

В реальных приложениях вы обычно будете создавать экземпляр своего собственного класса, производного от Window Или одного их производных классов WinFx Framework, такого, как NavigationWindow. Окно, как и элементы управления, является элементом визуального дерева, поэтому вы модифицируете отображаемое содержимое окна путем установки его свойства Content. В данном случае установите в нем простую строку, а класс Window Сам способен отобразить ее за вас. В типичном случае вы образуете содержание UI окна, конструируя дерево из других элементов и устанавливая верхний объект этого дерева в качестве свойства Content Для окна. Как только вы установили для содержимого окна строку «Hello WinFx», вы показываете окно, вызывая его метод Show. Затем вы вызываете метод Run Объекта Application, Который организует цикл обработки событий, используемый Windows для коммуникации с запущенным приложением, точно так же, как это делается в сегодняшних приложениях WindowsForms. Обратите внимание на атрибут STAThread Для метода Main. В WinFx на Windows ХР он все еще необходим, так как WinFx заключает в оболочку некоторые из предоставляемых системой элементов управления, которые предназначены для выполнения в однопоточном разделе.

Интерфейс IListSource: экспонирование коллекций коллекций

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

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

Часто вам потребуется работать с коллекциями данных, которые связаны друг с другом. Наиболее частым случаем этого является работа с наборами данных в. NET. Набор данных можно рассматривать в качестве Коллекции коллекций, так как он может содержать набор таблиц. Каждая DataTable Является Коллекцией элементов данных, которыми являются строки данных . Вы можете также реализовать свой собственный специальный тип контейнера, который содержит другие коллекции, такой, как список списков. Или, возможно, ваш тип контейнера содержит единственный список, но вы хотите позволить потребителям использовать ваш объект как источник данных и получать из объекта список для целей привязки данных. Предположим, например, что у вас есть рабочий класс с именем InventoryManager, Который позволяет вам управлять позициями вашего инвентаря и получать к ним доступ для различных случаев применения. Допустим, вы захотите предоставить приложениям возможность привязки к вашему менеджеру инвентаря, причем менеджер контролировал бы, что будет экспонироваться для привязки данных, исходя из некоторого критерия, экспонируемого классом: У вас также мог бы быть контейнер с несколькими коллекциями, например, класс менеджера инвентаря, содержащий списки наличных позиций инвентаря, позиций, поставляемых по предварительному заказу, и поставщиков. В этом случае вы хотели бы предоставить потребителям простой способ получить список списков, которые содержит ваш объект. Интерфейс IListSource Поддерживает эти сценарии посредством двух своих элементов, описанных в 6. Он позволяет возвратить при вызове GetList Коллекцию по умолчанию . Этот список может быть либо простым списком объектов для привязки данных, либо списком списков, содержащихся в объекте. Если свойство ContainsListCollection Возвращает True, Предполагается, что список, возвращаемый GetList, Сам содержит списки.

Реляционный доступ к данным

вам требуется классы определяемые в

Имея дело с доступом к реляционным данным, вы обычно следуете одной и той же процедуре всякий раз, когда вам требуется войти в контакт с базой данных для извлечения или обновления данных. Вам требуется Классы, определяемые в ADO. NET, используются для инкапсуляции состояния и поведения, ассоциированных с каждым из этих пунктов. Центральной концепцией реляционного доступа к данным в. NET является модель отключенных данных. Очевидно, вы не можете исполнить запрос, если у вас нет действительного соединения с базой данных. Отключенный доступ к данным означает, что вы открываете соединение, используете это соединение для выдачи набора запросов, а затем закрываете соединение. Некоторое время вы можете продолжать в клиенте работу с данными, полученными от запроса. Затем в некоторый момент вы можете восстановить соединение с базой данных, чтобы либо выдать запросы на обновление, либо обновить свои собственные данные, но вы не поддерживаете соединение с базой данных открытым все время, пока работаете с данными. Работа с такой моделью данных сильно отличается от того, что имело место в традиционных API баз данных, где обычно предпочиталась подключенная модель. Это также отлично от концепции автономных операций в приложениях развитого клиента. Автономные операции сосредоточены на возможности кэширования операциональных данных на стороне клиента, которое позволяет продолжать поддерживать некоторые случаи применения, даже когда нет подключения к сети. Отключенный доступ к данным обычно предполагает, что соединение с сетью доступно, но вы просто не поддерживаете соединения с базой данных открытыми в течение всего периода работы приложения.

Два основных способа заполнения содержимым несвязанных столбцов

b первый из обработчиков хорошо

Есть два основных способа заполнения содержимым несвязанных столбцов: либо обрабатывая событие RowsAdded, Либо обрабатывая событие CellFormatting. Первый из обработчиков хорошо подходит для установки значения ячейки, когда требуется сделать значение доступным впоследствии для программного извлечения. Второй обработчик подходит для передачи значения, которое будет использоваться только в целях отображения и не будет сохраняться вместе с данными, содержащимися в коллекции ячеек сетки. Событие CellFormatting Может также использоваться для преобразования значений в ходе их отображения в ячейках, когда отображаться должно что-то отличное от действительных значений, сохраняемых в скрытых за сеткой данных. Сначала этот код извлекает данные таблицы Customers при помощи метода GetData Адаптера таблицы. Как обсуждалось ранее, адаптер таблицы был создан вместе с типизированным набором данных, когда вы добавили к своему проекту источник данных. Возвращаемая методом таблица устанавливается в качестве источника данных для источника привязки. Свойство AutoGenerateColumns Устанавливается равным False, Так как код заполняет коллекцию столбцов программным путем. Затем при помощи перегруженного метода Add Коллекции Columns, Который принимает имя столбца и текст заголовка, к сетке добавляются четыре столбца текстовых полей. Первые три столбца настраиваются для привязки к данным столбцов CompanyName, ContactName и Phone таблицы Customers, для чего после создания каждого столбца устанавливается его свойство DataPropertyName. Четвертый столбец является несвязанным и здесь только создается вызовом метода Add. Он будет заполняться позднее при обработке событий. Наконец, интересующие нас события связываются, посредством неявных делегатов, с методами, которые будут их обрабатывать.

Генерация тестовых данных для привязки

b обратите внимание на то

Это простой метод генерации тестовых данных, который создает коллекцию List<Customer> И затем заполняет ее двумя объектами Customer, С каждым из которых ассоциируются объекты Order. Обратите внимание на то, как код клиента использует коллекцию Orders Класса Customer, Вызывая методы класса List<T>, Например, Add, Просто путем обращения к самому свойству Orders И вызова его методов. Заметьте также, что код устанавливает обратную ссылку от объекта Order На его родительский объект Customer, Просто устанавливая свойство Customer Объекта Order На создаваемый в данный момент экземпляр Customer. Как только список конструирован, он возвращается вызывающей форме и может быть использован для привязки данных. Если вы закодируете все это или загрузите образец CustomBusiness — Objects с сайта этой книги, а потом запустите его, то должны увидеть данные, заполняющие обе сетки. Выбор текущего заказчика в верхней сетке должен определять то, какие заказы будут показаны в нижней, что можно видеть Вы сразу же должны заметить, что если свойство класса с единственным значением является ссылочным типом, как свойство Customer Класса Order, Оно по умолчанию появится в сетке, поскольку пример автоматически генерирует столбцы. К сожалению, появляющиеся при этом значения имеют мало смысла, так как сетка, чтобы получить строковые значения для отображения в ячейке, в процессе форматирования вызывает метод ToString Объектов. То же самое произойдет, если привязать это свойство для отображения в элементе управления ComboBox, ListBox Или TextBox. Метод ToString По умолчанию, наследуемый от базового класса System.Object, Возвращает в качестве строки полностью квалифицированное имя типа, которое, скорее всего, не то, что вы хотели бы показать.

Можно было бы справиться с этим, не генерируя столбцы автоматически и не отображая в сетке свойство Customer. Но В Зависимости от ситуации вам могло бы потребоваться использовать это свойство в сценариях привязки данных, и в этом случае, возможно, вы хотели бы отображать нечто осмысленное, когда оно привязывается к текстовому элементу управления. Это можно сделать просто путем переопределения в своем специальном рабочем объекте метода ToString. В данном случае это означает добавление в класс Customer Переопределения ToString, Которое просто возвращает имя заказчика: