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

Поддержка развитого декларативного программирования на этапе проектирования

именно этого ожидают от развитых

Выбор элемента управления в конструкторе с последующей установкой его свойств или использованием контекстных меню для изменения поведения этого элемента управления является одной из форм декларативного программирования. Именно этого ожидают от развитых элементов управления программисты Windows Forms, привыкшие к поддержке такой парадигмы программирования, обеспечиваемой в Visual Studio. Вы видели несколько простых примеров развитой поддержки конструктора в атрибутах, которые добавлялись к свойствам DataSource И DataMember В классе FilteredGrid. Вы увидите еще несколько, с атрибутами Toolboxitem И ToolboxBitmap, В следующем примере.

Для любых свойств, которые будут экспонироваться в окне Properties, вы должны также включить атрибуты Description И Category. Вы видели, что атрибуты, которые добавляются к вашему элементу управления и тип которых распознает Visual Studio, автоматически появляются в окне Properties При выборе этого элемента управления. Вы сможете редактировать эти свойства при помощи редакторов, ассоциированных в Visual Studio С их типом. Visual Studio Предлагает массу возможностей, позволяющих вам пойти гораздо дальше. Можно использовать разнообразные другие атрибуты для влияния на другие аспекты поведения времени разработки, и можно создавать специальные преобразователи типов, позволяющие окну Properties Преобразовывать строки в сложные типы, которые обычно им бы не распознавались. Можно проектировать специальные редакторы, подключаемые к окну Properties, так что вы сможете редактировать свои сложные типы графически, подобно тому, как вы редактируете свойство Anchor Или выбираете цвет в диалоге, который отображается для свойств типа Color. Можно также создавать отдельные классы конструктора, которые вы ассоциируете с элементом управления, чтобы обеспечить его альтернативное или расширенное отображение, когда он находится в конструкторе. Эти вопросы выходят за рамки данной книги, но вы можете прочитать о них в различных источниках по программированию поддержки конструктора Windows Forms. О дополнении элементов управления функциями времени разработки я рекомендую прочитать в книге «Windows Forms Programming In С#» Криса Селлса. Крис Селлс и Майк Вайнхардт написали также на эту тему две статьи, опубликованные в апрельском и майском выпусках журнала «MSDN» за 2003 год.

Приложение PagingSample

для получения набора данных о

В приложении PagingSample источник привязки MCustomersBin — DingSource Добавляется на форму из панели инструментов, без использования поддержки конструктора для соединения его к источнику данных. Для получения набора данных о клиентах этот код снова использует уровень доступа к данным из главы 2 и устанавливает таблицу Customers В качестве источника данных для источника привязки. Затем в качестве источника данных для сетки, текстовых полей и поля со списком задается источник привязки, как показано в листинге 3.6 Помимо загрузки и организации привязки данных метод OnFormLoad Выполняет назначение методов формы двум событиям. Первое из них — событие источника привязки PositionChanged. Это событие возбуждается при любом изменении текущей позиции в нижележащем источнике данных. Форма также назначает метод событию TextChanged Текстового поля позиции, показанного на рис. 3.4. Назначения для событий Click Командных кнопок перемещения вперед и назад здесь не показаны, поскольку они производятся в конструкторе, на странице Events окна Properties. Обработчики для командных кнопок и двух только что описанных событий приведены в листинге 3.7.

Как видно из приведенного кода, кнопки для перемещения по записям просто используют соответствующие методы MoveXXX Источника привязки, предоставляя последнему самому позаботиться о изменении позиции в источнике данных. Когда источник привязки это сделает, все привязанные к нему элементы управления автоматически обновятся в соответствии с новой текущей записью. Кроме того, когда источник привязки возбуждает событие PositionChanged, Вызывается метод обработчика OnPositionChanged. Этот метод обновляет текстовое поле позиции, чтобы оно отображало номер текущей записи. Метод OnPositionTextChanged Позволяет ввести пользователю в этом поле новый номер записи и явным образом использует его для установки свойства Position Источника привязки.

Обратите внимание на метод TryParse, Новинку среди примитивов. NE Этот метод позволяет выполнить анализ введенной строки, не выбрасывая исключение в случае, когда анализ терпит неудачу. В нашем коде TryParse Используется для проверки на тот случай, когда пользователь вводит недействительный номер.

Дополнительные окна или формы входящие в состав вашего приложения

вам может понадобиться всплывающий диалог

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

Если вы просто хотите открыть новое окно для представления некоторых дополнительных данных, вы создаете экземпляр класса формы для этого окна и вызываете метод Show, Чтобы его отобразить:

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

Работа в коде с коллекцией реализующей IList

вы можете объявить экземпляр коллекции

Работа в коде с коллекцией, реализующей IList, Достаточно проста. Вы можете объявить экземпляр коллекции, добавлять к ней элементы методом Add, Находить элементы при помощи IndexOf, Определять, сколько их в коллекции, при помощи реализованного элемента Count Унаследованного интерфейса ICollection, Производить итерацию по всем элементам коллекции и обращаться к элементам, индексируя коллекцию с помощью индексатора IList Или через унаследованную поддержку интерфейса LEnumerable, И все это потребует весьма немногих строчек кода: В этом коде использован экземпляр обобщенного типа List<T>, Который реализует за вас IList для любого специфицированного параметра типа. Как уже упоминалось, когда вы объявляете переменную обобщенного типа с параметром типа, как в приведенном выше коде объявлена MyCollection С параметром типа Int, То в действительности вы создаете новый тип, являющийся сильно типизированным списком целых чисел, и, наряду с типом, объявляете экземпляр этого типа, все в одной строчке. Если коллекция поддерживает интерфейс IList, Вы сможете привязать ее к любому элементу управления Windows Forms из. NET Framework, который поддерживает привязку данных, посредством либо простой , Либо сложной привязки данных . Если элемент управления поддерживает модификацию коллекции , Вы можете добавлять элементы к коллекции, удалять их или редактировать значения элемента, экспонируемые в свойствах содержащихся объектов. Внутренний код привязки данных элемента управления итерирует содержимое коллекции и индексирует ее, используя свойства и методы IList. Как только элемент управления получит доступ к элементу коллекции, он может воспользоваться классом PropertyDescriptor, Чтобы динамически найти информацию о свойствах элементов коллекции, и использовать ее для заполнения любых своих свойств или визуальных элементов, которые привязаны к данным. В разделе главы 8 о дескрипторах свойств вы найдете более подробную информацию и примеры реализации специальных привязанных элементов управления.

Добавление к коллекции функций сортировки

прежде всего имеется ряд методов

Реализация сортировки несколько сложнее. Прежде всего, имеется ряд методов и свойств базового класса, которые вы должны переопределить. Кроме того, код и применяемый для сортировки алгоритм с необходимостью несколько более сложны. Имеется четыре свойства, которые требуется переопределить: SupportsSortingCore, IsSortedCore, SortDirection — Соге И SortPropertyCore. Требуется переопределить также два метода: ApplySortCore И RemoveSortCore. Если бы вам просто требовалось поддерживать сортировку коллекции, все было бы не так сложно. Трудность представляет возможность удаления сортировки. Когда вы сортируете коллекцию, вы должны сделать так, чтобы с момента сортировки любой использующий коллекцию код видел ее переупорядоченной. Это означает, что вы должны действительно изменить содержимое коллекции, расположив ее в другом порядке, чтобы любой код, когда он итерирует коллекцию при помощи базовой реализации интерфейса LEnumerator, Видел сортированный порядок. Поскольку требуется поддерживать удаление сортировки, вам нужен также способ вернуть содержимое коллекции обратно к первоначальному порядку. Простейшим способом сделать это является создание копии коллекции в ее несортированном состоянии до применения сортировки, а затем вы можете восстановить исходную коллекцию, когда сортировка удаляется. Однако здесь появляется другой уровень сложности — что будет, если в коллекцию добавляется или из коллекции удаляется элемент в то время, пока она сортирована? Элемент будет добавлен к сортированной коллекции, но если вы не будете перехватывать любые модификации коллекции, новый элемент или удаленный элемент не будет отражен в копии исходной коллекции, которую вы собираетесь восстановить при удалении сортировки.