5. Общее представление об интерфейсах привязки данных

Вездесущий DataSet

привязка данных к специальным объектам

Наиболее частым типом данных, с которым вы будете иметь дело в привязке данных Windows Forms, является DataSet. Привязка данных к специальным объектам и коллекциям в. NET 2.0 также очень проста, поэтому это также будет весьма распространенным подходом, который более подробно описывается в различных местах этой книги. Но наборы данных специально предназначены для привязки данных в. NET, а это приложение фокусирует внимание на реляционном доступе к данным, поэтому прежде всего мы займемся именно ими. По существу набор данных предоставляет вам коллекцию данных в памяти, которая может использоваться для хранения чего угодно, начиная от единственной строки данных до сложных схем из нескольких таблиц с отношениями и ограничениями между ними. Некоторые могли бы зайти даже так далеко, чтобы назвать их базами данных в памяти, но здесь существует та опасность, что при таком образе мыслей можно начать накапливать в памяти слишком много данных. Рис. Г.1 показывает структуру набора данных и объекты, которые содержатся внутри него. В случае простого табличного доступа к данным, полученным от запроса, вы обычно будете иметь дело с единственной таблицей в наборе данных, который будет целью вашей привязки данных. При этом набор данных становится просто красивой оберткой для набора строк. На самом деле вы могли бы просто создать таблицу данных и заполнить ее, и. NET 2.0 позволяет вам создавать самостоятельные объекты DataTable, Без охватывающего их набора данных. Существует также много сценариев, где вам может потребоваться извлекать строки из таблицы, которые находятся в родительско-дочерних отношениях со строками из другой таблицы. В таких случаях вы будете работать с наборами данных, содержащими несколько объектов таблиц данных, один или несколько объектов отношений данных, которые поддерживают родительско-дочерние отношения между таблицами, и объекты ограничений, обеспечивающие целостность содержащихся данных. Объект таблицы данных содержит коллекцию столбцов данных, которые описывают имя и тип каждого столбца в таблице, а также содержит коллекцию объектов строк данных, которые содержат собственно действительные данные.

Установка свойства DataSource

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

Теперь все, что потребуется для одновременного изменения привязки всех элементов управления — это установка свойства DataSource Объекта источника привязки, при этом все привязанные к нему элементы управления автоматически переключатся на новый источник данных. Например, вы можете получить отфильтрованный список клиентов из уровня доступа к данным и захотите привязать этот новый список к тому же набору элементов управления. Для подобной динамической смены источника необходимо, чтобы форма нового источника данных должна быть той же, что и у исходного источника. Например, вспомогательный метод AddTextBoxDataBindings Для каждого текстового поля добавляет привязку данных к столбцам CompanyName, ContactName И т. д. Если вы в качестве источника данных для источника привязки установите вместо коллекции клиентов коллекцию заказов, все эти привязки окажутся нарушенными — в новой коллекции элементов данных они не смогут найти привязанные свойства и поэтому будут выбрасывать исключения. На протяжении всей книги я буду более глубоко рассматривать разнообразные ситуации в сценариях привязки данных, где вступает в игру компонент BindingSource. Как правило, следует всегда между элементами управления и источниками данных располагать источники привязки, даже если вы не собираетесь динамически менять источник во время выполнения. Компонент BindingSource Предусматривает также средства для управления текущей записью в источнике данных, а также может возбуждать события, позволяющие отслеживать изменения в источнике данных.

Интерфейс lEditableObject: поддержка транзакционных модификаций элемента

потребляющий код может i b

Интерфейс LEditableObject Позволяет отложить фиксацию изменений свойств объекта до момента завершения процесса редактирования. Потребляющий код может Ушным Образом объявить, что на объекте начинается операция редактирования, а впоследствии принять либо отвергнуть изменения, сделанные в одном или нескольких свойствах объекта, прежде чем эти изменения станут видимы для другого кода, который может работать с этим объектом, оворя конкретнее, этот интерфейс позволяет, пока объект редактируется, отложить уведомление привязанных элементов управления об изменениях до момента, когда операция редактирования будет завершена вызовом EndEdit. Обычно вам может потребоваться реализовать этот интерфейс, если ваш объект имеет взаимосвязанные свойства или вам нужно верифицировать значения нескольких свойств, прежде чем можно будет сказать, что редактирование дало законное сочетание значений. Если вы разобрались в обсуждении интерфейса ICancelAddNew, То понять IEditableObject Будет несложно. Этот интерфейс позволяет поддерживать ту же транзакционную семантику на уровне индивидуального элемента данных. Если вы когда-нибудь редактировали таблицу данных, привязанную как к сетке, так и к другим элементам управления на форме, то вы видели этот интерфейс в действии. Когда вы изменяете в сетке значение столбца и затем переходите к другому столбцу, изменившееся значение не отражается в других привязанных элементах управления, пока фокус ввода не не покинет строку, которую вы редактируете. Если прежде перемещения фокуса вы нажимаете Esc, сделанные вами изменения откатываются и в отредактированные столбцы снова помещаются старые значения. Когда вы переводите фокус на другую строку, то в этот момент изменения редактируемой строки фиксируются, после чего другие элементы управления на форме будут обновлены, чтобы отразить новые значения. Это объясняется тем, что редактирование значения отдельного столбца рассматривается как часть единственной транзакции с объектом, и операции редактирования не считаются с точки зрения других элементов управления завершенными, пока операция не будет зафиксирована явно. Это происходит, когда вызывается метод EndEdit Объекта, либо сеткой при при смене текущей строки, либо вы явно вызываете его для фиксации изменений.

Привязка провайдера ошибок к источнику данных

класс b errorprovider b экспонирует

Вы можете также привязать провайдер ошибок к источнику данных и предоставить ему самому извлекать любую информацию об ошибках из источника данных. Класс ErrorProvider Экспонирует свойства DataSource И DataMember, При помощи которых его можно привязать к источнику данных таким же образом, как и другие привязанные элементы управления на форме. Если ошибка устанавливается через источник данных, и элементы данных в источнике реализуют интерфейс IDataErrorinfo , то провайдер ошибок будет показывать ошибки, как описано выше, для любых элементов управления, которые привязаны к элементам данных с ошибками в источнике данных. Вы можете сделать так вместо явного вызова SetError Провайдера ошибок в обработчике события Validating Для каждого элемента управления, если объекты в источнике данных поддерживают свою собственную информацию об ошибках. Однако при этом вам все равно может понадобиться предоставлять имеющиеся в источнике данных сообщения об ошибках, вызывая метод SetError Провайдера ошибок, если вы обнаруживаете в ваших формах определенные виды ошибок, так как источник данных не имеет контекстной информации о том, где и как он используется, в то время как коду вашей формы это известно.

Элемент управления DataGridview Требует особого подхода в отношении отображения информации об ошибках из-за сложности данных, которые он может показывать. Элемент управления DataGridview Имеет встроенную поддержку отображения информации об ошибках на уровне как строки, так и ячейки. Она работает очень просто. Точно так же, как при работе с провайдером ошибок на уровне формы, вы устанавливаете свойство ErrorText Строки или ячейки. Если свойство установлено, то в строке или ячейке будет отображаться значок, аналогичный значку провайдера ошибок, и всплывающая подсказка будет показывать установленный вами текст сообщения об ошибке. Обычно вы будете устанавливать только одно свойство из двух. Как можно видеть из рис. 10.4, значок появляется в ячейке заголовка строки, когда вы устанавливаете свойство ErrorText Строки, и в правой части ячейки, когда вы устанавливаете свойство ячейки.

Управление модификациями данных в сетке

после того как данные занесены

Элемент управления DataGridView Предоставляет вам явный контроль на тем, смогут ли пользователи редактировать, удалять или добавлять строки сетки. После того как данные занесены в сетку, пользователи могут взаимодействовать с представленными данными различными способами, что обсуждалось ранее. По умолчанию в число этих взаимодействий входят редактирование ячеек в строке, выбор строки и ее удаление клавишей Delete на клавиатуре, либо добавление новой строки, для чего используется пустая строка, отображаемая в качестве последней строки сетки.

Однако если вы собираетесь отслеживать изменения в источнике данных, то лучше будет следить за соответствующими событиями компонента BindingSource, А не подписываться на события самой сетки. Это особенно относится к случаю, когда код, используемый вами для обработки события, воздействует на другие элементы управления на форме. Поскольку везде, где это возможно, следует привязывать элементы управления не к самому источнику данных, а к источнику привязки, последний является наилучшим местом для отслеживания изменений в источнике данных. Если вы хотите запретить какие-либо из этих операций, установите в False Свойства AllowUserToAddRows Или AllowUserToDeleteRows, Либо установите в True Свойство Readonly Соответственно для добавления, удаления или редактирования. Каждое из этих свойств также возбуждает при установке своего значения соответствующее событие XXXChanged. Когда вы поддерживаете добавление, редактирование или удаление, вам может потребоваться обработка некоторых дополнительных событий для приема новых значений в несвязанных столбцах или при виртуальном режиме, как будет описано далее в этой главе.