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

Возбуждение событий изменения элемента

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

Есть еще один интерфейс, реализованный в классе BindingList<T>, Который вы, возможно, захотите переопределить в своих классах специальных коллекций для развитых сценариев: интерфейс IRaiseitemChangedEvents. В нем определено единственное булево свойство RaisesItemChangedEvents. В реализации класса BindingList<T> Это свойство возвращает False, Но вы можете при желании переопределить его в производном классе. Если вы возвращаете True, Показывая, что вы возбуждаете события изменения элемента, ожидается, что при изменении элементов в вашей коллекции вы будете возбуждать событие ListChanged. Если элементы вашей коллекции реализуют интерфейс INotifyPropertyChanged, Как было описано выше, это будет происходить автоматически. Но вы можете все равно поддерживать события изменения элемента, даже если объекты вашей коллекции и не поддерживают INotifyProperetyChanged. Однако к реализации IRaiseitemChangedEvents Следует подходить с осторожностью: для больших коллекций она может значительно ухудшить производительность, так как вы должны рефлектировать каждый объект при добавлении его в вашу коллекцию. В результате вызова AddValueChanged Метод, на который указывает делегат, будет вызываться всякий раз, когда значение свойства объекта изменяется посредством вызова метода SetValue Дескриптора свойства, а именно так привязанные к данным элементы управления редактируют источник данных. Все это будет совершенно бесполезно, если какой-то код получит ссылку на объект и будет устанавливать свойство через его установщик в определении свойства. Однако возвратный вызов будет активировать целевой метод всякий раз, когда свойство изменяется через привязанный элемент управления, поскольку именно через дескриптор привязанные элементы управления устанавливают свойства, не имея информации времени компиляции об объектах, к которым они привязаны. Следующий код показывает дополнительные методы, введенные в Binding — Listview<T> для поддержки уведомлений об изменении элемента. Класс BindingList<T> Уже реализует IRaiseitemChangedEvents, Но возвращает False, Указывая на отсутствие поддержки. Чтобы показать, что вы добавили поддержку, вам нужно реализовать интерфейс заново и возвратить True

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

генерируемый конструктором код будет содержать

Элементы управления имеют значения по умолчанию для всех свойств, которые они экспонируют, и именно эти значения будут использоваться в случае, если не установлено явно никакого другого значения. Генерируемый конструктором код будет содержать только тот код для установки свойств, где устанавливаются значения, отличные от значений по умолчанию. Например, когда вы ранее кодировали класс формы вручную и запускали приложение, строка заголовка была пуста, поскольку вы не установили свойство Text самой формы. Когда вы создаете форму в конструкторе, он сначала автоматически устанавливает в свойстве Text имя формы, и именно оно отображается в строке заголовка и в конструкторе, и во время исполнения. Вы можете изменить это свойство, как и любое другое, либо через окно Properties, либо программно. Значения свойств, которые были установлены равными чему-то иному, чем значения по умолчанию, будут выделены в окне Ptroperties жирным шрифтом. Как указывает комментарий к методу InitializeComponent, вы должны избегать непосредственной модификации кода этого метода. Масса этого кода переписывается всякий раз, когда вы модифицируете что-то на вашей форме в конструкторе. Поэтому в зависимости от характера кода, который вы добавляете или модифицируете в методе, ваши модификации могут быть утеряны, когда вы в следующий раз поправите что-то в конструкторе. Так что закройте этот файл, если он у вас открыт; я только хотел, чтобы вы получили возможность заглянуть в то, что происходит за кулисами. Как упоминалось выше, первое, что делает конструктор формы — это вызывает метод InitializeComponent, чтобы привести все элементы управления в то начальное состояние, которое вы специфицировали посредством визуального конструктора. Если вы хотите программно как-то иначе установить свойства или инициализировать другие элементы, которые не были объявлены посредством операций перетаскивания, то можете ввести в конструктор формы любой специальный код инициализации после вызова InitializeComponent.

Если вы совершенный новичок в программировании Windows Forms и в Visual Studio, этот пример мог показаться вам гораздо более сложным, чем простое написание кода вручную, из-за описания особенностей различных окон, визуального конструктора и кода, генерируемого в результате действий в конструкторе. Но фактом является то, что для многих вещей, которые вам придется делать в программировании Windows Forms, вы сможете достигнуть результата при помощи конструктора гораздо быстрее, чем вы написали бы весь код вручную, особенно, когда вы станете более уверенно и удобно чувствовать себя в работе с конструктором и IDE.

Свойство AllowEdit

этот обработчик производит простые проверки

Свойство AllowEdit Извлекает или устанавливает соответствующее свойство инкапсулированной коллекции BindingList, Которое проверяет обработчик события щелчка мыши, чтобы решить, следует ли производить обработку редактирования. Этот обработчик производит простые проверки на попадание щелчка в прямоугольники, вычисленные и сохраняемые методом UpdateCoordinates, И если он видит, что щелчок произошел внутри одного из столбиков, то увеличивает или уменьшает его значение на 10 процентов в зависимости от того, какая кнопка произвела щелчок. Теперь нужно добавить соответствующую поддержку в элемент управления DataBoundBarChartControl, Чтобы обновлять соответствующий источник данных, если это необходимо, и управлять редактируемостью отдельных элементов управления BarChartControl. Модифицированные фрагменты кода элемента управления выделены в листинге 8.12 жирным шрифтом.

Для отслеживания информации, достаточной для изменения привязанного списка данных при изменениях внутри отдельного экземпляра BarChartControl, Было добавлено несколько новых элементов класса: Ссылка на сам привязанный список, чтобы избежать многократного разрешения этой ссылки через синхронизатор. Когда источник данных обновляется и вызывается метод UpdateDataBinding, Вы сохраняете ссылку на привязанный список и устанавливаете флаг, показывающий, является ли источник обновляемым, исходя из состояния либо флага IList. IsReadOnly, Либо свойства IBindingList. AllowEdit В зависимости от того, реализует ли источник данных интерфейс IBindingList. При добавлении каждого элемента управления BarCharControl К вашему списку Controls Инкапсулирующий элемент управления подписывается на его событие DataValueChanged И устанавливает его редактируемость в зависимости от редактируемости списка. Наконец, обработчик для события DataValueChanged Любого из инкапсулированных диаграммных элементов управления, используя объектную ссылку на отправителя и индекс измененного столбика, обращается обратно к этому элементу управления, извлекает изменившееся значение, находит соответствующий объект в привязанном списке данных по индексу, сохраняемому для этого элемента управления в Hashtable, И устанавливает значение соответствующего свойства этого объекта в зависимости от действительного типа значения.

Класс Sort Comparer

b когда класс b list

Класс SortComparer Обеспечивает базовую реализацию сравнения, которая должна использоваться с методом List.Sort. Класс SortComparer Позволяет конструировать экземпляр класса, специфицировав свойство объектов, которое будет сравниваться для определения отношений «равно», «больше» или «меньше», передаваемое в дескрипторе свойства, и значение из перечисления ListSortDirection. Когда класс List<T> Производит итерацию по списку, применяя внутренний алгоритм сортировки, он вызывает метод Compare, Передавая ему два объекта, с которыми он в данный момент работает в процессе сортировки. Реализация Compare Из листинга 9.4 пробует различные способы сравнения объектов. Сначала она извлекает значение специфицированного свойства каждого из объектов при помощи метода Getvalue Дескриптора свойства. Затем она проверяет, реализует ли объект, который представляют эти значения, интерфейс IComparer. Это стандартный интерфейс в. NET Framework. Он реализует метод CompareTo, Инкапсулирующий ту же логику, к которой мы стремимся — говоря конкретнее, если объект сам решает, что он равен другому переданному объекту, он возвращает О; если он больше, он возвращает 1; если он меньше, он возвращает —1. Если значения свойства не реализуют IComparer, Но метод Equals Значения говорит, что оно равно другому объекту, то Compare Возвращает О, сообщая о равенстве. Наконец, если ни одна из проверок не удалась, значения свойства преобразуются в строки и строковые представления сравниваются при помощи CompareTo, Который реализует класс String. Самое последнее, что делает метод — проверяет направление сортировки, и если оно указывает на нисходящую сортировку, он умножает возвращаемое значение на — 1, чтобы обратить смысл отношений больше/меньше. Чтобы производить сортировку из вашего класса BindingListview<T>, Вам необходимо предусмотреть переопределения всех относящихся к сортировке методов и свойств базового класса. Они показаны в листинге 9.5.

Объявление переменной типа List<T> Для сохранения несортированной коллекции при применении сортировки.

Изменение порядка столбцов

поскольку разные пользователи уделяют некоторым

Переупорядочение столбцов является встроенной функцией сетки, которая позволяет пользователям изменять порядок отображения столбцов в сетке во время выполнения. Поскольку разные пользователи уделяют некоторым столбцам больше внимания, чем другим, пользователи часто просят, чтобы у них была возможность самим устанавливать порядок отображаемых столбцов. Хотя такую возможность можно было бы поддерживать программно, удаляя столбцы из сетки и затем вставляя их в новой позиции, это потребовало бы в общем случае утомительного написания большого объема кода. Поэтому разработчики группы Windows Client были настолько любезны, что позаботились о встроенной функции переупорядочения в самом элементе управления сетки. В дополнение к общим свойствам и поведению, которые можно конфигурировать через контекстную закладку, есть масса других свойств и событий, конфигурацию которых можно задавать на этапе проектирования в окне Properties. Установка любого из этих свойств генерирует соответствующий код в методе InitializeComponent Неполного класса для формы, создаваемого конструктором. Что особенно важно, в окне Properties можно конфигурировать любые свойства привязки данных. Возможно, вы захотите устанавливать при помощи этого окна стили, поскольку вы сразу можете видеть результаты этих установок в конструкторе и убедиться, что получается именно то, что вам нужно. Более подробно стили обсуждаются в конце этой главы. Она работает следующим образом. Если свойство AllowUserToOrderColumns Установлено в True И пользователь захватывает и тянет мышью заголовок столбца, сетка позволяет перетащить и сбросить столбец в позицию, где он хочет его разместить. Столбцы справа от позиции сброса будут сдвинуты на одну позицию вправо, а столбцы, окружающие первоначальную позицию перемещаемого столбца, сомкнутся после того, как столбец будетперемещен. Рис. 6.6 показывает это в процессе выполнения. В данном случае захвачен и перемещается влево столбец QuantityPerUnit. Перетаскиваемый заголовок столбца обозначается серым прямоугольником соответствующего размера. Когда вы перемещаете курсор к одной из сторон другого столбца, граница между этим столбцом и смежным с ним темнеет, показывая, куда будет помещен перетаскиваемый столбец после того, как вы отпустите кнопку мыши.