1. Построение приложений с привязанными данными в Windows Forms

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

через этот интерфейс код потребителя

Интерфейс ITypedList Позволяет экспонировать или получать доступ к информации о типе относительно свойств, определяемых элементами коллекции. Через этот интерфейс код потребителя может сказать коллекции: «Расскажи мне все об элементах данных, которые ты содержишь». Эта информация широко используется конструктором Visual Studio, Когда вы на этапе проектирования декларативно конфигурируете привязанные элементы управления, например, при установке конфигурации столбцов сетки DataGridView В зависимости от типизированных свойств элементов в привязанной коллекции. Он может использоваться и во время выполнения, чтобы менять поведение в зависимости от динамически раскрываемых типов свойств элементов коллекции. Типы, реализующий интерфейс ITypedList, могут поддерживать раскрытие информации о типе содержащихся в них элементов данных, на этапе проектирования или во время выполнения. Классы DataView И Bin — DingSource Реализуют ITypedList, И информация, экспонируемая их реализациями, позволяет раскрывать информацию о типе относительно содержащихся элементов данных. Поскольку каждая таблица DataTable Экспонирует DataView По умолчанию, это делает информацию о типе для данных в DataTable Доступной через интерфейс ITypedList. Элементы этого интерфейса показаны в таблице 7.7. Описание метода GetltemProperties Может несколько напоминать порочный круг •— вы передаете массив дескрипторов свойств, чтобы получить обратно коллекцию дескрипторов свойств. Проще всего понять, что здесь происходит, если разобраться в реализации DataView Этого интерфейса. Если вы получите интерфейсную ссылку ITypedList На DataView И вызовете затем через нее GetltemProperties С параметром Null, То метод возвратит коллекцию объектов PropertyDescriptor, Которые описывают каждое поле таблицы данных, на которую ссылается псевдотаблица. Листинг 7.1 далее в этой главе демонстрирует пример использования GetltemProperties Для получения дескрипторов свойств столбцов в таблице.

Интерфейс ICollection: управление доступом к коллекции

b он является производным от

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

Возможно, самым важным и часто используемым элементом, входящим в интерфейс ICollection, Является свойство Count. Если у вас есть коллекция, которая реализует только LEnumerable, То единственным способом выяснить, сколько в ней элементов — это получить перечислитель и и перебрать все элементы, подсчитав их в своем собственном цикле. Писать такого рода код очень скучно и долго, в то время как коллекции, реализующие ICollection, Позволяют пользователям получать число элементов в коллекции прямо из свойства Count, Что возлагает бремя о этого значения на класс-реализатор, как и должно быть.

Метод СоруТо Позволяет потребителю коллекции получить копию всех элементов коллекции в форме типизированного массива, так что он может оперировать этими элементами, не беспокоясь о других потребителях коллекции. Метод принимает два аргумента: ссылку на массив и индекс, указывающий, с какого элемента коллекции должно начинаться копирование. Массив, передаваемый вызывающим, должен иметь тип, подходящий для размещения элементов коллекции, и размер, достаточный для копирования всех элементов, начиная с указанного индекса. Конечно, прежде чем воспользоваться этим методом, вы должны принять во внимание и издержки производительности, связанные с копированием каждого элемента. Если же приемлемо непосредственное манипулирование элементами коллекции, то не стоит и беспокоиться о предварительном их копировании в отдельный массив.

Если коллекция поддерживает одновременный доступ из нескольких потоков, ее нужно синхронизировать. Это означает, что в ней должен быть реализован механизм блокировки, гарантирующий, что не будет возникать состояний «гонок», когда, например, один поток пытается обратиться к элементу коллекции, который был только что удален другим потоком. Детали синхронизации выходят за рамки этой главы, однако есть много других книг, предоставляющих сведения по этой теме.

Перехват добавлений и удалений

вам нужно позаботиться также о

Для перехвата добавлений и удалений вам нужно переопределить еще некоторые методы базового класса BindingList<T>, Такие, как Insertltem, Removeltem И Clearltems, И обеспечить выполнение одних тех же изменений как в первичной, так и в несортированной коллекции. Вам нужно позаботиться также о транзакционных добавлениях к коллекции, поэтому потребуется переопределение EndNew И CancelNew, А также транзакционное удаление из несортированной коллекции. Как видите, все усложняется весьма быстро. Чтобы продемонстрировать базовые возможности сортировки, давайте не будем поддерживать добавление и удаление элементов, когда коллекция сортирована. Вам все равно потребуется сделать копию существующей коллекции перед применением сортировки и возвратиться к этой копии, когда сортировка отменяется, но вам не нужно будет беспокоиться о добавляемых или удаляемых элементах и о поддержке параллельной коллекции, когда коллекция сортирована. Как уже упоминалось, класс List<T> Имеет встроенную возможность сортировки, и вы можете воспользоваться ей для выполнения действительной сортировки. Класс производит сортировку, исходя из обобщенной реализации интерфейса Icomparer<T>, Которую вы передаете методу. Для реализации этого интерфейса вы создаете класс с методом Compare, Который сравнивает объекты типа т и возвращает целое, показывающее, равен ли первый объект второму, больше он или меньше второго объекта. Какой критерий вы используете для решения о том, какое значение возвращать, определяется вами и вашей реализацией интерфейса. Реализация в листинге 9.4 использует идеи, взятые из рубрики Майкла Вайнхардта «Wonders of Windows Forms» в «MSDN Online», которые сами восходят к более ранней статье Рокки Лотка. Я выбрал другую стратегию реализации и добавил возможность сортировки по нескольким свойствам, которая показана далее в обсуждении реализации интерфейса IBindingListView, но некоторые основные детали следующей реализации были взяты из серии статей Майкла «Custom Data Binding» в зимних выпусках 2004 года.

Интерфейс ICurrencyManagerProvider: экспонирование контейнером объекта CurrencyManager

этот интерфейс реализуется компонентом i

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

Интерфейс ICurrencyManagerProvider Имеет два элемента: метод с именем GetRelatedCurrencyManager И Свойство С Именем CurrencyManager. Вы будете пользоваться главным образом свойством CurrencyManager, Чтобы получить ссылку на нижележащий синхронизатор и подписаться на его уведомления об изменениях. Метод GetRelatedCurrencyManager Позволяет специфицировать параметр компонента данных, чтобы получить синхронизатор дочерней коллекции в сценарии ведущий-детализация. В этой главе были охвачены все основные интерфейсы привязки данных, которые вам может потребоваться реализовывать либо потреблять. Я показывал их, подходя к ним с точки зрения контракта, представляемого интерфейсом, после чего описывал интерфейс более подробно, отправляясь от его элементов. Для описания и демонстрации наиболее сложных концепций я привел несколько примеров, а также описывал некоторые моменты в плане реализации и использования интерфейсов, как они присутствуют в уже знакомых вам элементах управления и коллекциях. NET Framework, таких, как DataView И DataGridView. Существует еще несколько интерфейсов, работающих за кулисами, таких, как IBindableCompo — Nent, Реализуемый в Windows Forms базовым классом Control. Но поскольку вам не придется в действительности иметь дело непосредственно с ними, я не стал вдаваться в их детали. Вот некоторые ключевые выдержки из этой главы: Минимальным требованием к коллекции данных является реализация интерфейса IList, Который позволяет привязать коллекцию непосредственно к элементу управления. Компонент BindingSource Может производить итерацию по коллекции, которая реализует только LEnumerable, И добавлять ее элементы к своей собственной внутренней коллекции-списку, поэтому для поддержки привязки через BindingSource Достаточно интерфейса LEnumerable.

Элемент управления Grid View

net был b datagrid b

Вероятно, самым распространенным элементом управления в привязанных к данным приложениях ASP. NET до появления ASP. NET 2.0 был DataGrid, Позволяющий представлять табличные данные. Как и элемент управления DataGrid В Windows Forms, DataGrid В ASP. NET было удобно использовать в простых сценариях, но в случае более сложных он оставлял желать много лучшего. Поэтому разработчики ASP. NET пошли по тому же пути, что и команда разработчиков Windows Client — вместо того, чтобы «исправлять» или улучшать существующий элемент управления, поддерживая при этом обратную совместимость, они решили совсем его заменить. В результате появился GridView.

В простых сценариях элемент управления GridView Функционирует во многом аналогично DataGrid. Вы устанавливаете для него источник данных, как-то стилизуете, и когда происходит привязка к данным, элементы привязанной коллекции отображаются в качестве строк HTML-таблицы, где каждый столбец или свойство в источнике данных выводится в отдельном столбце строки. Однако возможности Gridview Простираются гораздо дальше и делают как обычные, так и более сложные сценарии намного проще. Например, как упоминалось ранее, для поддержки редактирования, выбора, сортировки и пагинации элемент DataGrid Требовал при обратных отсылках обработки событий, которые были не настолько просты или очевидны, чтобы разобраться в них с первой попытки. В элементе Gridview Вы просто устанавливаете свойство элемента управления, указывая, что он должен поддерживать одну или несколько из этих функций, а элемент сам об этом позаботится. Для самых распространенных сценариев вся обработка отсылок инкапсулирована, но события все равно возбуждаются, позволяя вам единообразно обрабатывать особые ситуации. Улучшены возможности стилизации сетки, как и возможность применения шаблонов для специального содержимого ячеек.