4. Привязка объектов контроля к источникам данных

Метод AddNew

метод b addnew b возвращает

Метод AddNew Позволяет добавить новый элемент непосредственно и получить обратно ссылку на добавленный элемент, позволяющую редактировать его свойства. Метод AddNew Возвращает экземпляр того типа, на который настроен источник привязки. Если до вызова AddNew Тип не был установлен, будет добавлен экземпляр типа Object, Что довольно бесполезно. Поэтому вызывать AddNew Имеет смысл только после того, как будет установлено свойство DataSource Или при помощи метода Add В список будет добавлен первый объект конкретного типа. Вызов AddNew Инициирует вызов метода EndEdit и фиксирует все изменения в текущей строке нижележащего источника данных. Текущим становится новый элемент, добавленный вызовом AddNew. Наконец, AddNew Возбуждает событие AddingNew, Которое можно использовать для инициализации нового объекта значениями по умолчанию, либо вы можете для нового объекта действительно создавать объект и возвращать его через обработчик события, как показано

В листинге 4.4 на событие источника привязки AddingNew Подписывается обработчик события OnAddingNew. Обратите внимание, что при подписке на событие в конструкторе формы не создается явным образом новый объект делегируемого типа, а применяется синтаксическая форма C# для вывода делегата. Этот новый элемент языка C# обеспечивает более компактную нотацию создания делегатов для обработчиков событий или параметров возвратно-вызываемых методов. Обработчик AddingNew Конструирует новый объект и возвращает его через аргумент события, а затем код в обработчике события Load Модифицирует свойство этого объекта, устанавливая значение, отличное от значения по умолчанию.

Удалить элементы из коллекции данных, содержащейся В Источнике привязки, вы можете также при помощи методов Remove И RemoveAt. Метод Remove Принимает ссылку на объект и ищет в списке экземпляр этого объекта, и если он найден, удаляет его. Метод RemoveAt Принимает индекс и удаляет элемент, находящийся в указанной позиции. Удалить из списка сразу все элементы можно вызовом метода Clear.

Интерфейс ICancel Add New

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

Для поддержки такого сценария был определен интерфейс ICancelAddNew, Позволяющий коллекции выносить решение о принятии либо отклонении нового элемента, добавленного к коллекции посредством методов этого интерфейса. Если коллекция поддерживает транзакционное добавление элементов, в ней должен быть реализован интерфейс ICancelAddNew. Привязанные элементы управления могут тогда вызывать EndNew, Чтобы фиксировать транзакцию добавления нового элемента, либо CancelNew , чтобы отменить добавление. Это позволяет элементу управления вызвать метод списка AddNew, Получить от него новый элемент и начать установку значений нового объекта. Если код вызовет CancelNew С индексом добавленного элемента, новый объект может быть отброшен, не будучи действительно добавленным в коллекцию. Если код вызовет EndNew С этим индексом или произведет над коллекцией какую-то другую операцию, добавление будет зафиксировано. Самому объекту совершенно не нужно знать о своем промежуточном характере принадлежности к коллекции; всем распоряжается сама коллекция.

Такое поведение несколько отличается от того, что можно было бы ожидать. В мире распределенных транзакций с базами данных подразумевается, что вы должны явно фиксировать транзакцию, иначе она будет отменена. В случае интерфейса ICancelAddNew Поведением по умолчанию в соответствии с контрактом, специфицированным инфраструктурой Framework, является фиксация, даже если EndNew Не будет вызван явно. Таким образом, вставка или удаление других элементов, как и установка в качестве текущего другого элемента коллекции, рассматривается как операция, снимающая фокус ввода с добавляемого элемента и фиксирующая его в коллекции. Как класс BindingList, Рассматриваемый в главе 9, так и класс BindingSource Реализуют этот интерфейс для коллекций, которыми они управляют. Поскольку обобщенный класс BindingList Не может знать, что делать с транзакционной семантикой вызовов AddNew Или CancelNew, То для подходящей к вашему сценарию их реализации вам нужно будет произвести от BindingList Новый класс, заменив в нем методы AddNewCore И CancelNewCore Базового класса.

Интерфейс IBindingList: расширенная поддержка привязки

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

Интерфейс IBindingList Является важнейшим интерфейсом в плане поддержки развитой привязки данных. Он определяет средства для контроля над изменениями в списке, сортировки и поиска в списке, а также обеспечивает выдачу уведомлений об изменениях, когда содержимое списка меняется. В .NET 2.0 вы можете легко создать частичную реализацию IBindingList при помощи обобщенного класса коллекции BindingList<T>. Как уже упоминалось, реализация IList Является единственным барьером, который нужно преодолеть, чтобы обеспечить привязку элементов управления Windows Forms. Однако простая реализация этого интерфейса недостаточна для поддержки той развитой привязки данных, к которой привыкли разработчики, имея дело с коллекциями вроде DataView. Важнейшим интерфейсом для поддержки привязки с модификациями коллекции данных является IBindingList. Такие модификации осуществляются либо через сам привязанный элемент управления, либо производятся «за кулисами» путем программных изменений в коллекции. Интерфейс IBindingList Позволяет также коллекции указать, поддерживает ли она сортировку или поиск, и предусматривает методы, которые будут приводить эти процессы в движение. IBindingList Является производным от IList, Поэтому при реализации IBindingList Вам нужно будет реализовать все элементы интерфейсов IList, ICollection И LEnumerable. Лучше всего сделать это путем использования либо наследования обобщенного класса BindingList<T>. В главе 9 разрабатывается законченный пример, показывающий, как это делается, с добавлением реализаций для IBindingListView, ITypedList И I Raise ItemChangingEvents. Если вам нужна более подробная информация о потреблении интерфейса IBindingList И о том, какие функции обеспечиваются каждым из его элементов, читайте дальше.

Разрешение конкуренции данных

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

Проблемы конкуренции данных проявляют себя в различных ситуациях, чаще всего в распределенных многопользовательских системах. Основная проблема конкуренции данных состоит в том, что при работе с отключенными данными, что по большей части и делается через ADO. NET, одни и те же данные могут редактироваться одновременно двумя различными пользователями или двумя различными частями кода. Когда сделанные изменения будут фиксироваться в хранилище данных, вам придется решать, чьи данные сохранять и что делать с конфликтами. Как описывается в приложении Г, когда в ADO. NET происходит ошибка конкуренции, на уровне доступа к данным выбрасывается исключение DBConcurrencyException. В больших промышленных системах эти ошибки часто перехватываются на рабочем уровне или под ним, и обрабатываются некоторым автоматическим образом, с возбуждением, возможно, како — го-то другого типа ошибки для уровня представления, чтобы оповестить пользователя. В меньших системах вы можете позволить исключению DBConcurrencyException Пройти наверх вплоть до уровня представления, чтобы там его обработать. Возможно также, что вы решите в ответ на ошибку конкуренции возбуждать на рабочем уровне специальное исключение. Какой бы подход вы ни избрали, для разрешения этих ошибок или представления их пользователю не существует никаких «встроенных» функциональных средств. Подготовленность пользователей в различных прикладных областях очень сильно варьируется, и соответственно варьируется степень сложности решений, которые вы можете оставить на их усмотрение, и это не дает возможности найти такие решения общего назначения, которые подошли бы всякому. Если ваши пользователи знают довольно много, вы могли бы в случае ошибок конкуренции предоставлять им UI, который позволяет сделать выбор между значениями, которые он посылают, и текущими значениями в базе данных, как показано на рис. 10.7. В случае менее подготовленных пользователей вы могли бы просто отвергать посланные ими данные и заставлять их ввести все заново. Тут вы должны продумать вопрос, как часто это может происходить и какое воздействие будет оказывать на пользователей, хотя иногда требование проделать лишнюю работу, заново вводя данные, будет меньше сбивать с толку и будет связано для них с меньшим стрессом, чем попытки понять, чего от них хочет более сложный интерфейс.

Класс SqlParameter

он отвечает за управление трансляцией

Класс SqlParameter Инкапсулирует передачу параметров сохраняемым процедурам и параметризованным запросам. Он отвечает за управление трансляцией параметров между двумя различными системами типов: системой типов. NET и системой типов базы данных. Система типов. NET содержит такие примитивы, как Int32, Float, Double, DateTime И String, А также все остальные классы. NET Framework и любые специальные классы и структуры, которые вы пишете. Эта система типов сохраняет значения в наборе данных, поскольку набор данных является просто еще одним типом в мире. NET, который способен содержать другие типы. NET посредством объектных ссылок. SQL Server имеет свою собственную концепцию системы типов, и именно эта система типов используется для сохранения данных в базе данных. Итак, класс SqlParameter Берет на себя заботу об инкапсуляции значений в системе типов. NET и передаче их базе данных в форме, которая совместима с действующей там системой типов. Вы конструируете каждый объект SqlParameter, Специфицируя имя параметра запроса, который он будет представлять, тип базы данных для параметра запроса и размер этого параметра, если в базе данных это тип переменной длины. Имеются различные перегрузки конструктора SqlParameter, Которые позволяют вам опустить спецификацию размера, и вы, кроме того, всегда можете установить эту информацию через свойства. Параметр имени, передаваемый конструктору, должен в точности соответствовать имени параметра запроса, включая символ @ в параметрах SQL. Это является специфическим для управляемого провайдера SQL Server. Если вы используете управляемый провайдер OLE DB, то там соответствующим классом будет OleDbParameter. Однако параметры OLE DB всегда передаются по их позиции в операторе, так что имя параметра игнорируется.