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

Обработчик OnGetvisited Count для события Click

b если вы запустите приложение

Обработчик OnGetvisitedCount Для события Click Кнопки отображает диалог, показывающий число отображавшихся строк, которое определяется по состоянию коллекции M Visited. Если вы запустите приложение VirtualMode, то заметите несколько моментов, о которых стоит упомянуть. Первый касается того, что самое большое влияние на время выполнения оказывает время загрузки и кэширования на стороне клиента большой коллекции данных. Вследствие этого в реальном приложении вы, возможно, захотите выполнять такого рода операцию в отдельном потоке, чтобы не блокировать UI во время загрузки данных. Для этого можно было бы воспользоваться компонентом BackgroundWorker. Если при работе с большими объемами данных пользователь перетаскивает кнопку прокрутки, большое число строк на самом деле пропускается механизмами навигации и из-за задержек самой полосы прокрутки. В результате вам придется предоставлять лишь малый процент действительных значений ячеек, если только пользователь не прокручивает сетку слишком интенсивно. Вот почему виртуальный режим хорош для вычисляемых значений: можно избежать вычисления значений для ячеек, которые отображаться не будут.

Если вы запустите пример и немного поупражняетесь с прокруткой, а затем щелкнете на кнопке Get Visited Count, то увидите, сколько строк было загружено на самом деле. Я, например, запустил это приложение и прокрутил сетку сверху донизу несколько раз, довольно медленно. Я наблюдал по видимости плавную прокрутку, как будто я действительно проходил по всем миллионам строк, представленным в сетке. Однако как оказалось, в процессе прокрутки отображено было всего около 1000 строк.

Как быть, если вы захотите поддерживать редактирование значений непосредственно в сетке? Может быть, вы применяете виртуальный режим только для того, чтобы представлять вычисляемый столбец с относительно небольшим набором данных, и собираетесь использовать отредактированное значение в этом столбце для выполнения каких-то других вычислений или сохранить это значение. Есть еще одно событие, CellValuePushed, Которое запускается по завершении редактирования ячейки в сетке виртуального режима.

Тип List

это позволяет писать сильнее типизированный

Тип List Реализует интерфейсы IList, ICollection И LEnumerable Для поддержки нетипизированной привязки данных, а также и обобщенные версии этих интерфейсов , Дающие вам строго типизированный доступ к содержанию коллекции посредством программирования с опорой на интерфейсы. Это позволяет писать сильнее типизированный и менее зависимый код для программного манипулирования содержанием коллекций через интерфейсные ссылки, вместо прямого программирования для конкретного типа коллекции. Благодаря реализации в типе List<T> Интерфейса IList Вы можете легко привязать коллекцию объектов любого типа, создав экземпляр List<T> И использовав в качестве типового параметра специальный тип объекта, как было показано выше для типа Customer. Таким образом, вы сможете использовать экземпляр List<T> В качестве источника данных для привязки к элементам управления на форме, а также отслеживать коллекции дочерних объектов через элемент List<T> Объекта, содержащего ссылки на дочерние объекты.

В именном пространстве System.Collections .Generics Были добавлены и другие обобщенные классы коллекций, включая Dictionary<T>, Queue<T>, Stack<T> И SortedDictionary<T>. Дополнительным обобщен-ным классом коллекции, чрезвычайно полезным в сценариях привязки данных, является тип BindingList<T>, Обсуждаемый далее в этой главе. На самом деле тип BindingList<T> Лучше всего подойдет для коллекций объектов, которые вы намереваетесь использовать в привязке данных. На самом деле в других отношениях класс List<T> Мощнее, чем класс ArrayList. Он предусматривает развитый поиск, сортировку и управление доступом, что до. NET 2.0 обычно приходилось реализовывать вручную.

DataBoundBarChartControl в действии

в настоящем случае мы специфицировали

Как только вы начинаете разработку специализированным сценариям привязки данных такого рода, вы сразу покидаете область обобщенной привязки данных, которая поддерживается элементами управления Framework. В настоящем случае мы специфицировали, что данные, поддерживаемые элементом управления, должны иметь конкретную форму. Мы могли бы сделать это более явным, определив, возможно, специфический интерфейс, который должны поддерживать коллекции данных, скажем, IDecisionSupportDataList, А затем программировать, ориентируясь на экспонируемые им методы или свойства. Это было бы аналогично тому, как элементы управления Framework предполагают, что данные поддерживают интерфейс IList. Однако для многих сценариев это может быть стрельбой из пушки по воробьям, и вы захотите поддерживать лишь определенную форму данных, исходя из предположений о том, какого вида данные должны оказаться в привязанных к элементу управления источниках данных, и только соответствующим образом обрабатывать ошибки, если эти предположения не оправдываются. С таких позиций мы и подойдем к реализации этого примера. Определение отдельного интерфейса, описывающего определенного рода коллекцию данных, имело бы смысл, если вы собирались определить несколько элементов управления, которые делали бы одни и те же предположения относительно формы данных, но это возложило бы дополнительное бремя реализации нестандартного интерфейса на любые коллекции данных, которые вы хотите использовать с вашими элементами управления, что ограничило бы их полезность. Итак, давайте разработаем элемент управления, который выглядит подобно показанному на рис. 8.9. Он должен обеспечивать данные, динамически управляющие представлением, моделируя поддержку привязки данных элементами управления Windows Forms из Framework. Кроме того, он должен поддерживать и реляционные источники данных, такие, как набор данных, и коллекции специальных рабочих объектов. Предполагается, что коллекции данных, предоставляемые в форме источника и компонента данных, имеют единственный столбец, который идентифицирует строку и будет использоваться в качестве ее метки. Ожидается также, что коллекция будет иметь произвольное число дополнительных столбцов или свойств численных типов, которые будут использоваться для генерации столбиков вместе с их значениями и именами свойств.

Программирование приложения WinFx

winfx основана на сложной но

Когда вы программируете приложения WinFx, у вас есть два возможных подхода; вы можете избрать один из них или использовать смешанный подход. WinFx основана на сложной, но вполне понятной объектной модели, поэтому вы можете писать приложения целиком на удобном для вас развитом языке программирования. Для кодирования элементов UI и объектов, из которых составляется ваше приложение, вы можете также использовать совершенно новый декларативный язык, опирающийся на XML, который называется Extensible Application Markup Language. Можно встраивать в файл XAML логический код в виде блоков сценариев на C# или Visual Basic, либо можно разместить логический код в отдельном исходном файле, а в XAML-файле только объявлять разметку, описывающую элементы UI. В сущности XAML обеспечивает декларативный подход к созданию пользовательских интерфейсов, схожий с тем, что используется в разметке ASP. NET, но который можно применять как для Web-, так и для Windows-приложений. Как и в ASP. NET, у вас есть возможность привязать к объявленным в XAML элементам управления логический код поддержки из компилированных исходных файлов, а среда времени выполнения присоединит этот компилированный код при динамической компиляции разметки и сценариев, содержащихся в XAML-файле. Код XAML обладает перед исходным кодом несомненными преимуществами с точки зрения разработчика, пользующегося специальными инструментами, и может оказаться гораздо более компактным, чем соответствующий программный код. Лично я полагаю, что WinFx-приложения пользовательского интерфейса будут по большей части писать с использованием XAML для декларативного создания элементов UI. Но, видимо, к тому времени, как вы действительно энергично приметесь за программирование WinFx-приложений, уже будут инструменты, генерирующие XAML по интерактивным указаниям в конструкторе, и вам редко, если вообще придется самим непосредственно редактировать код XAML. Однако если вы любите XML или имеете солидный опыт программирования приложений ASP. NET, то вы, возможно, вполне непринужденно нырнете и будете плавать в море угловых скобок, и даже будете получать удовольствие от программирования XAML. В конце этого приложения есть несколько примеров с XAML, которые дадут вам преставление о том, как выглядит код XAML, соответствующий ранее разработанному коду одного из образцов.

Источники привязки

я большой сторонник использования в

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

Можно сделать так, чтобы форма в качестве параметра своего конструктора получала ID клиента, извлекала необходимые данные, редактировала их, а затем записывала обратно в базу данных. Затем вам потребовалось бы по завершении диалога обновить главную форму, чтобы она отразила изменения в источнике данных. В зависимости от того, позволяет ли сама сетка редактировать данные, такой подход может породить проблемы конкуренции, даже если речь идет о единственном пользователе вашего приложения, и это, конечно, не лучший путь с точки зрения обмена с базой данных. На самом деле вам нужно, чтобы две раздельных формы работали с одним и тем же источником данных в памяти. Тогда вы сможете в качестве параметра передавать конструктору формы редактирования источник привязки, к которому она должна привязываться, получая его от формы-листинга, которая запускает редактирующую форму, как это проделано в следующем коде. В этой форме используется простая привязка между отдельными текстовыми полями и соответствующими компонентами в источнике данных через переданный форме источник привязки. Теперь при любых изменениях, вносимых в форму редактирования, они будут автоматически отражаться в исходных данных, поэтому сетка на форме, которая запускает форму редактирования, будет также синхронизована с этими данными. Все, что должна теперь делать кнопка Save, — это закрывать форму, при этом данные будут сохранятся в источнике данных на стороне клиента. Если вы хотите в этот момент зафиксировать изменения в базе данных, вы можете добавить код, выполняющий через уровень доступа к данным дополнительный вызов для сброса изменений в базу.