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

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

все что для этого нужно

Небольшой, но мощный и удобный элемент управления PictureBox Можно использовать, когда вам нужно поместить на форме изображение. Все, что для этого нужно сделать — это конструировать объект класса Bitmap Из пространства имен System.Drawing И присвоить его свойству Image Элемента управления PictureBox. Последний имеет также свойство SizeMode, Которое можно устанавливать равным Normal, AutoSize, Center — Image, Stretchlmage Или Zoom. В зависимости от значения, которое вы установили для SizeMode, Элемент управления PictureBox Будет автоматически управлять изменением размера изображения, когда форма, на которой он находится, будет перерисовываться или изменять свой размер. Элемент управления DataGrid Был оплотом табличного представления данных в. NET 1.x. Он позволяет вам привязывать наборы данных, таблицы и коллекции данных к сетке для отображения в табличной форме. Элемент управления может обнаруживать отношения между несколькими таблицами в наборе данных и предусматривает схему навигации между родительскими и дочерними строками данных. Он позволяет легко сортировать строки по выбранному столбцу и настраивать представление столбцов и всей таблице посредством классов стилей. Однако поскольку у DataGrid Было много проблем как в плане удобства применения, так и в плане настройки, в. NET 2.0 был введен элемент управления DataGridview. Этот элемент управления стал преемником DataGrid В качестве основного элемента управления для табличного представления данных в новых приложениях. Если вы обновляете существующие приложения, которые используют DataGrid, Вам не обязательно переходить на DataGridview. Ваш существующий код с DataGrid Будет продолжать работать, как прежде, но я не рекомендую применять элемент управления DataGrid В каком-либо новом коде приложений. NET 2.0.

Работа с транзакциями

это можно сделать внутри sql

Иногда вам требуется возможность исполнять несколько команд в пределах области действия единственной транзакции с базой данных, чтобы в случае, когда любая из команд терпит неудачу, терпели неудачу они все, и никаких изменений в базе данных не производилось бы. Это можно сделать внутри SQL Server и других баз данных, начиная транзакцию внутри сохраняемой процедуры и фиксируя либо откатывая ее в зависимости от результатов запросов, инкапсулированных внутри процедуры. Однако иногда вам нужно контролировать транзакцию из вашего кода ADO. NET, заключив в одну транзакцию исполнение нескольких команд. Сделать это довольно просто. Вы можете использовать класс SqlTrans — Action в сочетании с соединением, чтобы управлять транзакцией из своего кода доступа к данным. Допустим, например, что вы хотите написать код, который сначала проверял бы, существует ли строка, и если существует, то делал какие-то модификации этой строки. Давайте также допустим, что вам нужно это сделать посредством двух явных текстовых SQL-запросов из вашего управляемого кода. Вы хотите написать непробиваемый код, поэтому должны быть уверены, что строка, которая будет подвергаться обновлению, не будет модифицирована или удалена другим клиентом или запросом в промежутке между моментом, когда вы проверяете ее существование, и моментом, когда вы ее обновляете. Использование транзакции с соответствующим уровнем изоляции отлично подойдет для такого сценария. Взгляните на код в листинге Г.9.

Здесь следует обсудить несколько моментов. Первый — как создать и применить транзакцию. Код создает соединение и объекты команд, как вы уже видели раньше. Транзакция создается вызовом BeginTransaction Для соединения с необязательной спецификацией уровня изоляции. Уровень изоляции по умолчанию — ReadCommitted, Но чтобы гарантировать, что никто не сможет модифицировать запись после того, как она была прочитана оператором SELECT, вам нужен ReadRe — Peatable.

Так что же такое XAML?

я начал свое изложение с

Большинство пользовательских интерфейсов WinFx будут, скорее всего, программироваться с помощью XAML. Я начал свое изложение с объектов и программного кода, чтобы подчеркнуть тот факт, что объекты, с которыми вы имеете дело в WinFx, — это просто новый набор элементов управления и классов из новой группы именных пространств, дополняющий существующую инфраструктуру. NET Framework. Однако помимо объектов, поддерживающих новые возможности WinFx в плане пользовательских интерфейсов, вводится и новый язык для спецификации кода этих интерфейсов. XAML дает в руки программистам, пишущим UI для Windows, возможности декларативной разметки с использованием XML, которой уже многие годы пользуются разработчики Web-приложений и которая часто позволяет проще специфицировать расположение и свойства элементов UI. Теоретически никому никогда не придется непосредственно редактировать XAML или какую-то другую форму кода XML. Инструментальные средства должны скрывать XML, позволяя вам манипулировать объектами в конструкторе более простыми способами, а в качестве результата этих манипуляций должен генерироваться соответствующий код XML. Можно надеяться, что к моменту выхода WinFx на рынок такие инструменты будут и в Visual Studio.

Но пока вам придется кодировать XAML вручную при помощи текстового редактора. В Visual Studio 2005 имеется, правда, привязанная к схеме поддержка IntelliSence в редакторе XML, которая может подсказывать вам допустимые элементы и атрибуты в зависимости от того, в каком месте дерева элементов XAML вы находитесь. Но все равно вы пишете XML вручную, что оставляет желать много лучшего.

В качестве примера я воссоздам пример DataBindinglOl, который показан на рис. Б.2 — окно с полем списка заказчиков и два текстовых поля, привязанных к одной коллекции, отображающих имя заказчика и телефонный номер из текущей записи, — но реализую приложение, используя смесь XAML и программного кода.

Определение специального типа ячейки

если вы собираетесь рисовать самостоятельно

Первым шагом реализации приложения будет определение специального типа ячейки. Если вы собираетесь рисовать самостоятельно, можно переопределить защищенный виртуальный метод Paint Базового класса DataGridViewCell. Однако если содержимое ячейки, которое вы хотите отображать, является лишь вариацией одного из встроенных типов ячеек, то следует рассмотреть возможность наследования от одного из этих типов. Именно это я и сделал в данном случае. Поскольку мои специальные ячейки должны показывать изображения, естественным базовым классом для них будет DataGridViewlmageCell. Однако мой класс StatusCell Не будет предусматривать возможность установки произвольных изображений; он предназначен для работы с перечислимыми значениями. Я хочу также, чтобы ячейка могла оперировать целыми значениями, если они укладываются в диапазон соответствующих численных значений перечисления, чтобы можно было поддерживать обычную ситуацию, когда перечислимые типы сохраняются в базе данных как целые значения. Код листинга 6.4 показывает реализацию класса StatusCell. В этом коде сначала объявляется перечисление Statuslmage. Оно будет ожидаемым типом для свойства Value Данного типа ячейки. Далее вы видите, что тип StatusCell Является производным от DataGridViewImage — Cell, Поэтому я могу воспользоваться способностью последнего представлять изображения внутри сетки. Имеется поле состояния по умолчанию и соответствующее свойство, позволяющее непосредственно прочитать значение состояния по умолчанию. Конструктор, кроме того, устанавливает для свойства ImageLayout Базового класса значение Fill, Поэтому изображения масштабируются так, чтобы они вписывались в ячейку без искажения.

Ключевым моментом в специальном типе ячейки является либо переопределение метода Paint, О чем уже упоминалось, либо переопределение метода GetFormattedValue, Что и делается в классе StatusCell. Этот метод будет вызываться всякий раз при отображении ячейки, и позволяет вам обрабатывать преобразование значений других типов в тип, ожидаемый ячейкой. Я решил, что код метода GetFormattedValue В этом примере должен сначала установить для ячейки некоторое значение по умолчанию, на случай, если ничего другого сделано не будет. Затем код пытается получить действительное значение по умолчанию из свойства Defaultvalue Содержащего ячейку столбца, если это столбец типа StatusColumn . Код проверяет, что текущее свойство Value Является перечислимым типом Statuslmage Или целым, и если оно целое, приводит значение к перечислимому типу.

Свойство DataSource

b если сам источник данных

Свойство DataSource Может устанавливаться на любую коллекцию объектов, которая поддерживает один из четырех интерфейсов: IList, IList — Source, IBindingList Или IBindingListView. Если сам источник данных является коллекцией коллекций данных, такой, как набор данных, или источник реализует интерфейс IListSource, То свойство DataMemder Должно идентифицировать в источнике данных ту коллекцию, к которой производится привязка. Если свойство Datasource Установлено на объект, реализующий IList , ТО Свойство DataMemder Может быть равно Null . Когда вы привязываете DataGridView К источнику привязки, то поскольку сам класс BindingSource Реализует интерфейс IBindingListView , вы можете в действительности привязать сетку к любой коллекции, с которой может работать источник привязки, в том числе к простым коллекциям, реализующим только IEnumerable. Всякий раз, когда устанавливается свойство Datasource И/или свойство DataMemder, Сетка будет перебирать находящиеся в коллекции данных элементы и обновлять привязанные к данным столбцы таблицы. Если сетка привязана к источнику привязки, любые изменения в скрытом за ним привязанном источнике данных будут также приводить к обновлению привязанных столбцов сетки. Это происходит благодаря событиям, возбуждаемым источником привязки в привязанных элементах управления при любых изменениях в лежащей под ним коллекции.

Всякий раз при установке свойств Datasource И DataMemder Они запускают соответственно события DataSourceChanged И DataMemberChanged. Это позволяет вам подключить код, исполняемый в ответ на изменение привязки данных в сетке. Вы можете также реагировать на событие DataBin — DingComplete, Поскольку оно запускается после того, как изменяется источник или элемент данных и обновляется привязка данных.