5. Общее представление об интерфейсах привязки данных

Создание приложений Windows Forms при помощи Visual Studio

обычно вы будете пользоваться интегрированной

Написание формы вручную полезно для понимания простоты модели, но вы редко будете писать код Windows Forms полностью от руки. Обычно вы будете пользоваться интегрированной средой Visual Studio для проектирования форм способом ускоренной разработки приложений. Давайте разберем пример. Если вы хотите отменить поведение по умолчанию, при котором создается отдельная папка для решения, либо изменить имя этой папки, вы можете сделать это при помощи опций в нижней части диалога. Следует сделать пару важных замечаний относительно кода, который вы написали к настоящему моменту. Первое — то, что это просто код. Здесь интегрированная среда разработки не творила от вашего имени никаких чудес. Чтобы получить довольно развитое представление привязанных данных, вам нужен всего лишь текстовый файл с несколькими строчками исходного кода, XML-файл, содержащий некоторые данные, и компилятор с командной строкой. Еще можно отметить, что если у вас на форме много элементов управления, то кодирование инициализации их свойств очень быстро может стать весьма утомительным. К счастью, конструктор Windows Forms в Visual Studio напишет весь этот код за вас, a Visual Studio предоставит гораздо более ясную среду, чтобы вы располагали на форме элементы управления визуально, а не ломали голову над тем, какой код вы должны для этого написать. Поэтому вы редко будете писать код инициализации для элементов управления вручную, как делали здесь. Наконец, сложности привязки данных и отображения данных на форме полностью инкапсулированы в элементе управления сетки, и все происходит благодаря простой установке его свойства DataSource На действительный источник данныхСоздав проект, Visual Studio создаст главную форму для вашего приложения и покажет ее в окне конструктора внутри главной рабочей области.

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

Метод Begin Edit

это необходимо поскольку в зависимости

Как вы можете видеть из кода, метод BeginEdit сохраняет текущие значения полей в кэшируемых полях и устанавливает флаг, показывающий, что вы находитесь в режиме редактирования. Это необходимо, поскольку в зависимости от того, как организована привязка данных, BeginEdit может вызываться формой неоднократно, и вы хотите сохранить старые значения в именно в тот момент, когда редактирование действительно началось, но не повторно, когда вступает в действие остальная часть процесса редактирования. Метод EndEdit по существу принимает текущие значения, устанавливая флаг редактирования обратно в false. Метод CancelEdit откатывает изменения, устанавливая текущие значения свойств в первоначальное состояние, используя кэшированные значения. Реализовав таким образом IEditableObject, ваш специальный рабочий объект сможет теперь вести себя подобно набору данных, когда будет редактироваться в сетке вроде DataGridView. А именно, если несколько свойств некоторой строки были отредактированы, а затем пользователь нажимает клавишу Esc, изменения будут откачены и в объекте будут восстановлены исходные значения. Такая простая реализация не учитывает тот факт, что концептуально коллекция orders также может быть изменена в ходе логического редактирования объекта Customer. Вы, возможно, захотите обеспечить откат и этих изменений, поскольку заказы являются дочерними объектами, и логически они «являются частью» объекта Customer. Однако поскольку интерфейс IEditableObject в основном используется в контексте привязки данных, вам, чтобы модифицировать коллекцию Orders, ассоциированную с выбранным заказчиком, придется переключить фокус на сетку Orders, а такое переключение фокуса в любом случае вызовет EndEdit для объекта Customer. Могут быть и более развитые сценарии, где вы, возможно, захотите реализовать интерфейс IEditableObject для поддержки полностью транзакционного редактирования объекта, как через привязанный элемент управления, так и программным путем, но на самом деле он для этого не предназначен.

Диалог Add Column

если вы добавляете столбец привязанный

Диалог Add Column позволяет добавить к сетке привязанный к данным либо несвязанный столбец. Если вы добавляете столбец, привязанный к данным, его можно выбрать из доступных столбцов в текущем выбранном источнике данных. Прежде всего нужно установить в качестве источника данных соответствующую коллекцию данных, либо через контекстную закладку, либо в окне Properties. Если добавляется несвязанный столбец, то вам нужно просто специфицировать имя столбца, его тип и текст заголовка. Когда вы нажимаете кнопку Add, столбец добавляется к сетке, а диалог остается открытым, так что можно быстро определить несколько новых столбцов. Определение конфигурации столбцов при помощи этих диалогов генерирует за вас весь код для определения столбцов и управления их поведением, который обсуждался в предыдущих разделах главы. Флажок Enable Adding в контекстной закладке DataGridView При перечеркивании устанавливает в True Свойство AllowUserToAddRows, Которое отображает в нижней части сетки пустую строку. Это позволяет пользователю добавить к коллекции данных новую строку, введя в ячейки новые значения. Будет ли это возможно, зависит от того, привязана ли сетка к данным, и если привязана, поддерживает ли нижележащая коллекция данных добавление новых элементов. Подобным же образом флажок Enable Editing сбрасывает Свойство Readonly, Которое определяет, могут ли пользователи редактировать содержимое сетки по месту, a Enable Deleting устанавливает свойство AllowUserToDeleteRows. Флажок Enable Column Reordering устанавливает свойство AllowUserToOrderColumns, Поведение которого описывается в следующем разделе.

Ссылка Dock In Parent Container доступна только в случае, если вы сначала перетащите на форму элемент управления сетки. Она просто устанавливает свойство Dock Равным Fill.

Добавление поддержки привязки данных к специальному элементу управления

начнем с простейшей задачи предоставим

Мы будем добавлять различные функции элемента управления постепенно, как это обычно и делается при разработке подобных элементов. Начнем с простейшей задачи — предоставим пользователям вашего элемента управления возможность указать источник и компонент данных для привязки инкапсулированной сетки к набору данных. Поскольку сетка DataGridview Является дочерним элементом вашего элемента управления, она объявляется как закрытый элемент его класса. Это относится по умолчанию и к любым другим элементам управления, которые вы перетаскиваете в рабочее пространство конструктора для формы или элемента управления. Объявление можно при желании изменить посредством свойства Modifiers В окне Properties Или путем прямого редактирования кода, генерированного конструктором. Вообще говоря, следует избегать непосредственной модификации генерируемого кода, так как ваши изменения могут быть переписаны в результате других операций в конструкторе; именно поэтому в Visual Studio 2005 весь этот код и размещается в отдельном файле неполного класса. В качестве одного из способов поддержки привязки данных к сетке в пользовательском элементе управления можно было бы разрешить пользователям непосредственно обращаться к инкапсулированной сетке и устанавливать ее источник данных. Но в свете предъявляемых к фильтрующей сетке требований это не годится, поскольку весь смысл в том, что мы создаем элемент управления, модифицирующий привязку к сетке в зависимости от значений, получаемых из текстового поля фильтра и из списка полей. Поэтому правильным путем организации привязки данных в вашем специальном пользовательском элементе управления будет имитация API привязки данных, экспонируемого другими привязанными элементами управления. Для отображения табличных данных это означает экспонирование вашим элементом управления свойств DataSource И DataMember, Позволяющих установить его привязку данных. Благодаря инкапсулированному источнику привязки вам не нужно будет самому делать какую-либо неприятную работу по привязке данных — вы просто перепоручаете ее источнику привязки. Продолжая процедуру, начатую в предыдущем разделе, сделайте следующее: Установите в окне Properties свойство DataSource Сетки На источник привязки . Благодаря этому при любом изменении источника данных в источнике привязке сетка будет автоматически обновляться. Теперь вы можете экспонировать в элементе управления свойства DataSource И DataMember, Делегировав их источнику привязки

Дескрипторы свойств: динамическое раскрытие информации об элементах данных

b этот класс определяется в

Важным классом, который позволяет коду привязки данных работать с любой коллекцией и типом элементов данных, является PropertyDes — Criptor. Этот класс определяется в пространстве имен System.Compo — NentModel И обеспечивает динамическое раскрытие информации о типах отдельных свойств объекта. Дескриптор свойства можно получить несколькими способами. Как рассказывается в последующих разделах, некоторые интерфейсы привязки данных имеют методы или свойства, возвращающие дескрипторы свойств. Вы можете также получить их из объекта, если у вас есть ссылка на него. Класс TypeDescriptor, Также из пространства имен System.ComponentModel, Позволяет запрашивать дескрипторы свойств для свойств объекта при помощи метода GetProperties. На самом деле в классе TypeDescriptor Есть масса других методов, которые позволяют вам динамически раскрыть почти все, что стоит знать об объекте, включая его методы, свойства, события, атрибуты и т. д. Как подразумевает их название, дескрипторы свойств используются для передачи информации о свойстве объекта. Класс PropertyDescriptor Является производным от MemberDescriptor, Который предоставляет много свойств, позволяющих раскрыть информацию об описываемом свойстве объекта. Вы можете выяснить имя свойства, его тип, что является для него преобразователем типа и какие атрибуты применялись к объявлению типа, к которому оно принадлежит. В том, что касается привязки данных, вас по большей части будут интересовать четыре свойства, экспонируемых классом PropertyDescriptor: Name, PropertyType, ComponentType И Converter. Каждое из них доступно только для чтения.