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

Интерфейс lEnumerator

более конкретно интерфейс b ibindinglistview

Метод должен возвращать объект-перечислитель, реализующий интерфейс LEnumerator.

Интерфейс LEnumerator Имеет три элемента и работает подобно «логическому курсору» в коллекции данных. Он отправляется от позиции, установленной непосредственно перед первым элементом коллекции. Его использование начинается с вызова метода MoveNext Перечислителя, который позиционирует курсор на первый элемент, если таковой имеется, и возвращает True. Если коллекция пуста, первый вызов MoveNext Возвращает False. Последующие вызовы MoveNext Перемещают курсор на следующий логический элемент коллекции, пока в ней больше не останется элементов. Метод продолжает возвращать True, Пока курсор к моменту завершения вызова устанавливается на элемент коллекции. Когда элементов больше нет, MoveNext Возвращает False. Такая модель позволяет изящно и компактно организовать итерацию, поместив вызов MoveNext В цикл While. Порядок передвижения логического курсора определяется реализатором интерфейса LEnumerator И не обязан соответствовать физическому порядку следования элементов в коллекции. Например, если вы реализуете перечислитель для сортируемой коллекции, вы захотите, чтобы курсор перемещался в соответствии с порядком сортировки. Однако если вы собираетесь поддерживать сортировку, вам придется также позаботиться о реализации интерфейса IBindingList. К итерируемым элементам вы обращаетесь через свойство Current. Это свойство интерфейса LEnumerator Возвращает ссылку типа Object, Которая должна указывать на текущий элемент коллекции в позиции логического курсора. Интерфейс LEnumerator Включает также метод Reset, Возвращающий курсор к его начальной позиции, позволяя вам произвести повторную итерацию по той же коллекции, используя тот же самый перечислитель. Следующий фрагмент кода показывает типичный цикл, использующий интерфейсы Обобщенная коллекция List<T> Реализует интерфейс LEnumerable , Поэтому код посредством неявного приведения получает ссылку на интерфейс LEnumerable Коллекции. Затем он вызывает через эту интерфейсную ссылку метод GetEnumerator, Который возвращает интерфейсную ссылку типа LEnumerator. Имея перечислитель, вы на его методе MoveNext Организуете цикл While.

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

более конкретно интерфейс b ibindinglistview

Если вы помните из главы 7, существует уровень функциональных возможностей привязки данных, определяемый интерфейсом IBindingListView, Который вы можете поддерживать, чтобы сделать свои коллекции еще богаче. Более конкретно, интерфейс IBindingListView Вводит возможности сортировки более чем по одному свойству и фильтрации по некоторому выражению фильтра, которая позволяет показывать одновременно только часть нижележащей коллекции. Интерфейс IBindingListView Определяет четыре дополнительных свойства и два метода, которые вам нужно реализовать для полной поддержки интерфейса. Булевы свойства SupportsAdvancedSorting И SupportsFiltering Указывают, какие из двух возможностей вы поддерживаете. Свойство SortDescriptions Возвращает коллекцию ListSortDescriptionCoilection, Которая содержит любые критерии сортировки, действительные в настоящий момент. Каждый объект ListSortDescrip — Tion В коллекции является просто парой, ассоциирующей PropertyDescriptor И ListSortDirection Для каждого из свойств, к которым применяется сортировка. Свойство Filter Поддерживает установку и получение строки выражения фильтра, которую вы используете для настройки того содержания коллекции, которое представляется любому использующему коллекцию. Метод ApplySort Аналогичен тому, что определен в интерфейсе IBindingList, Но принимает параметр ListSortDescriptionCoilection Вместо одиночных PropertyDescriptor И ListSortDirection. Каждый ListSortDescription В этой коллекции содержит дескриптор свойства и направление сортировки, что позволяет сортировать по каждому критерию по очереди. Метод RemoveFilter Удаляет любой действующий в настоящий момент фильтр и восстанавливает коллекцию в ее полном содержании.

Хотя это звучит как нечто самоочевидное, реализация этого интерфейса дело нетривиальное. Сортировку по нескольким свойствам реализовать на самом деле довольно просто, но это требует некоторых расширений класса SortComparer<T> И логики сортировки, представленных ранее. Фильтрация может выполняться различными способами, но еще более усложняет положение дел, если вы хотите разрешить добавления и удаления из коллекции, пока она находится в фильтрованном состоянии. Будучи фильтрованной, ваша коллекция в принципе может еще и сортироваться, так что вы должны быть способны вернуться к исходному, возможно, модифицированному списку от сортированного/нефильтрованного, фильтрованного/несортированного и фильтрованного/сортированного состояний.

Отображение вычисляемых данных в виртуальном режиме

например вам нужно представить в

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

Работа с псевдотаблицами

псевдотаблица сама по себе не

Другим способом манипуляции данными, содержащимися в наборе данных, в целях обработки или просмотра является использование псевдотаблицы. Псевдотаблица сама по себе не содержит никаких данных; она является лишь некоторым видом на данные таблицы, находящейся под ней. Можете считать ее как бы объективом, который вы располагаете над таблицей и который заставляет ее выглядеть по-дру — гому для потребителя псевдотаблицы, хотя нижележащие данные остаются все теми же данными, сохраняемыми в таблице, которую псевдотаблица представляет. Вы можете модифицировать данные, экспонируемую через псевдотаблицу, и когда вы это делаете, вы в действительности непосредственно модифицируете данные в нижележащей таблице. Каждый экземпляр DataTable Уже имеет ассоциированный с ним экземпляр DataView По умолчанию, и в действительности именно он используется, когда вы привязываете таблицу к сетке. Вы можете делать модификации в псевдотаблице по умолчанию, что повлияет на все элементы управления, привязанные к нижележащей таблице, либо вы можете конструировать новые экземпляры объекта DataView Вокруг таблицы для целей сортировки или фильтрации данных. Класс DataView Реализует свойства Sort, RowFilter И RowstateFiIter, Которые позволяют модифицировать то, какие данные экспонирует псев — дотаблица. Вы устанавливаете в свойстве Sort Выражение, специфицирующее, по какому столбцу сортировать и в каком порядке. Вы можете установить выражение RowFilter, Используя тот же синтаксис, что поддерживается методом DataTable. Select, Для ограничения представленных в псевдотаблице строк в зависимости от некоторого критерия, сходного с предложением WHERE в операторе SQL. Наконец, вы можете использовать RowState Filter, Чтобы видеть только строки в определенном состоянии, только удаленные или только добавленные строки. Вы можете использовать все это в комбинации, чтобы специфицировать довольно сложные критерии фильтрации и сортировки для экспонирования содержащихся в таблице данных почти в любом необходимом вам виде:

Код пишет Visual Studio

вы можете сделать то же

Ясно, что когда весь этот код пишет Visual Studio, это удобнее и оставляет меньше места для ошибок, чем при собственноручном его написании. Вы можете сделать то же самое, программируя объекты самостоятельно. Например, если вам не требуется поддерживать обновление, то не нужно предусматривать команды вставки, обновления, удаления и их параметры. Можно также воспользоваться поведением Gridview по умолчанию, чтобы генерировать столбцы в зависимости от данных, к которым привязывается сетка. В результате код в листинге А. З, генерированный Visual Studio, может быть урезан до кода, показанного в листингах А. 4 и А. 5. Преимуществом элемента SqlDataSource Является быстрота. Вы можете перетаскивать объекты из Server Explorer на поверхность конструктора, а он будет генерировать соответствующий код, включаемый в вашу страницу. Можно воспользоваться также мастером Configure Data Source, чтобы определить запрос, ассоциированный с уже добавленным на страницу элементом источника данных. Это позволяет вам просто перетащить с инструментальной панели на страницу элемент управления SqlDataSource, А затем с помощью мастера генерировать код привязки.

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