Когда я знакомился с RAD Studio XE3, то упоминал о том, что механизм связывания данных, который ранее назывался просто LiveBindings, обзавелся теперь визуальными редакторами, которые значительно упростили создание различных связей в проектах. Теперь нет необходимости городить жуткие, как на первый взгляд, так и на второй выражения для создания связи — достаточно вызвать визуальный редактор и буквально в три клика связать TGrid с таблицей из БД, свойства различных компонентов и т.д. В общем идея Visual LiveBindings в Delphi XE3 мне понравилась настолько, что я решил покопаться в этом механизме чуть по-глубже. И сегодня я рассмотрю несколько примеров работы с Visual LiveBindings, в т.ч. и с новыми компонентами для связывания данных, такими как TPrototypeBindSource и TBindSourceDBX.
Содержание
- Помощник Visual LiveBindings
- Визуальный редактор LiveBindings
- Использование TPrototypeBindSource в LiveBindings
- Использование TBindSourceDBX на примере БД SQLite
Помощник Visual LiveBindings
Самое простое, с чего можно начать сегодняшний пост — это посмотреть, что представляет из себя визуальный редактор в LiveBindings. Чтобы было удобнее пользоваться этим редактором, первым делом зайдем в настройки IDE: Tools—>Options—>LiveBindings и поставим галочку напротив опции «Display LiveBindings Wizard in right-click menu»:
Теперь в контекстном меню появится новый элемент:
Теперь создадим простую связь — свяжем свойство Text компонента Edit и свойство Caption компонента Label. Бросаем на форму проекта компоненты Label и Edit и вызываем контекстное меню, например, у Label и выбираем пункт «LiveBindings Wizard…«. В итоге запуститься помощник создания связей LiveBindings, который будет содержать только те варианты связей, которые можно использовать для Label. В нашем случае, на первом шаге, Помощник предложит нам такие виды связей:
Так как мы сейчас связываем два свойства компонентов, то оставляем на этом шаге все как есть, т.е. должен быть выбран пункт «Link a property of Label1 to a control«. Жмем Next>>
На втором шаге нам предлагается выбрать связываемое свойство. Мы решили связывать Caption — его и выбираем:
Жмем Next>> и на третьем шаге выбираем компонент с которым будет создана связь. Здесь мы можем либо создать новый компонент для связи, либо выбрать уже существующий. Т.к. мы предварительно уже поместили на форму Edit, то его и выберем:
Обратите внимание на то, что в третьем шаге мы не указываем, что за свойство у Edit будет связываться — сейчас помощник подберет его сам, но в дальнейшем мы сможем его сменить. Жмем Finish. Всё связь создана. Однако, если вы сейчас запустите приложение и попробуете что-либо ввести в Edit, то можете обнаружить, что при этом значение Label.Caption не изменяется (а должно бы). Дело в том, что созданная только что связь никак не отслеживается. Для того, связь заработала так как мы предполагали, т.е. значение свойств менялось автоматически, достаточно установить у этой связи свойство Track в значение True.
Делается это просто. Сейчас на форме появился уже известный нам по Delphi XE2 компонент BindinsList — находим в нем наше выражение и меняем свойство Track:
Вот теперь можно запустить приложение, ввести что-нибудь в Edit, нажать Enter и убедиться, что выражение связывания TEdit.Text и TLabel.Caption работает.
Так работает помощник в Visual LiveBindings. Теперь на этом же самом примере посмотрим как можно сделать точно такую же связь, используя Визуальный дизайнер в LiveBindings. Для этого удаляем наш BindingsList с формы и переходим к следующей части статьи.
Визуальный редактор LiveBindings
Создадим ту же самую простую связь TEdit.Text—>TLabel.Caption используя визуальный редактор. Для этого снова вызываем контекстное меню любого компонента формы (например, Label’а) и выбираем пункт «Bind Visually…»
В результате этого откроется визуальный редактор LiveBindings, который, в нашем случае, будет содержать такие элементы:
Теперь достаточно просто «взять» мышкой свойство Text у Edit и перетащить его на Caption у Label. Получится вот такая связь, обозначенная стрелкой, идущей от Edit к Label:
Стрелка в визуальном редакторе — это и есть наше выражение для связывания, поэтому выбираем эту стрелку мышкой и снова ставим свойство Track в True. Всё готово. Можно запустить проект и проверить работу нашей связи. Вот таким простым способом можно создавать связи в Visual LiveBindings. Если хотите разобраться более подробно с тем из чего состоит визуальный редактор, что в нем можно сделать, то можете прочитать вот эту статью из официальной wiki Embarcadero.
С простым примером связывания данных в Visual LiveBindings разобрались, а теперь посмотрим как можно использовать различные компоненты LiveBindings, которые появились в Delphi XE3.
Использование TPrototypeBindSource в LiveBindings
В Delphi XE3 на палитре компонентов появилось сразу несколько новых компонентов для Visual LiveBindings и одним из них является TPrototypeBindSource. Этот компонент представляет из себя источник данных с помощью которого можно связывать данные, например, произвольных объектов (как это делалось в Delphi XE2 см. эту статью) и эта связь отображалась/редактировалась в Визуальном редакторе LiveBindings.
Для примера, рассмотрим как можно связать поля объекта с визуальными компонентами на форме, используя TPrototypeBindSource в Visual LiveBindings. Создадим в нашем проекте такой класс:
type TPerson = class private FName: string; FFamily: string; FBirthday: TDate; procedure SetBirthday(const Value: TDate); procedure SetFamily(const Value: string); procedure SetName(const Value: string); function GetFullName: string; public constructor Create(const AFamily, AName: string; ABirthDay: TDate); property Name: string read FName write SetName; property Family: string read FFamily write SetFamily; property FullName: string read GetFullName; property Birthday: TDate read FBirthday write SetBirthday; end; constructor TPerson.Create(const AFamily, AName: string; ABirthDay: TDate); begin inherited Create; FFamily:=AFamily; FName:=AName; FBirthday:=ABirthDay; end;
Класс содержит три свойства для чтения/записи — Name, Family и Birthday, а также одно свойство только для чтения — FullName. Теперь добавим на форму необходимые компоненты для вывода данных. Пусть это будут 3 Edit’а для свойств доступных для записи и 1 Label для свойства FullName. Моя форма стала выглядеть вот так:
Теперь нам необходимо поработать с TPrototypeBindSourse и создать в нем необходимые поля для работы с объектом, который будет иметь тип TPerson. Сделать мы это можем двумя способами — с использованием Помощника Visual LiveBindings или просто бросить на форму компонент TPrototypeBindSource и поработать с его свойствами. Например, рассмотрим создание TPrototypeBindSource в Помощнике. Делается все довольно просто — главное быть внимательным :) Итак:
1. Вызываем из контекстного меню формы Помощник LiveBindings и выбираем на первом шаге последний пункт:
Жмем «Next>>»
2. Выбираем в списке TPrototypeBindSource
Жмем «Next>>»
3. Добавляем необходимые поля
Для этого жмем «Add…», вводим название поле, выбираем его тип и жмем «Ok»:
После того как все поля добавлены жмем «Finish» и на форму будет добавлен компонент с названием PrototypeBindSource1:
Теперь осталось связать визуальные компоненты на форме с полями TPrototypeBindSource. Связывание будет проходить точно также как и в предыдущем примере с Label и Edit, поэтому повторяться не буду, а просто приведу вид визуального редактора LiveBindings с уже созданными связями:
Обратите внимание на то, что для свойств доступных для записи были созданы двунаправленные (linkBidirectional) связи — их мы можем редактировать. Теперь нам осталось только передать в TPrototypeBindSource необходимые объект. Сделать это можно, используя единственное событие компонента — OnCreateAdapter.
Для примера, создадим такое поле у класса формы:
type TForm19 = class(TForm) {...} private {...} public Person: TPerson; end;
Создаем обработчик OnCreateAdapter у PrototypeBindSource1 и пишем в обработчике:
procedure TForm19.PrototypeBindSource1CreateAdapter(Sender: TObject; var ABindSourceAdapter: TBindSourceAdapter); begin Person:=TPerson.Create('Иван','Иванов',StrToDate('01.12.1981')); ABindSourceAdapter:=TObjectBindSourceAdapter.Create(self,Person,True); end;
Здесь мы вначале создали объект TPerson, а затем, используя этот объект создали адаптер для TPrototypeBindSource. Созданный выше адаптер, как может быть понятно из его названия, используется для связи полей объектов (TObject, TFmxObject и т.д.) со свойствами визуальных компонентов.
Теперь можно запустить приложение и убедиться, что все созданные связи прекрасно работают:
Как видно на рисунке, все данные из объекта вывелись на форму. Теперь посмотрим как можно редактировать свойства объекта — связь-то у нас, как я говорил выше, двунаправленная. Чтобы продемонстрировать редактирование данных добавим на форму кнопку (TButton) и напишем в обработчике такой код:
procedure TForm19.Button1Click(Sender: TObject); begin //Смотрим, что содерится в объекте ShowMessage(Person.FullName+' '+DateToStr(Person.Birthday)); //Записываем изменение PrototypeBindSource1.Post; //Проверяем, что изменилось в свойства объекта ShowMessage(Person.FullName+' '+DateToStr(Person.Birthday)); end;
Теперь можно снова запустить приложение и попробовать изменить какое-нибудь значение, например, имя и убедиться, что изменения корректно применяются.
Использование TBindSourceDBX на примере БД SQLite
Как стало известно после выхода RAD Studio XE3, в DBExpress была добавлена поддержка БД SQLite, что меня очень порадовало, т.к. я использую SQLite в некоторых проектах. Наряду с этим в Visual LiveBindings появился довольно замечательный компонент TBindSourceDBX, позволяющий буквально в пару кликов связывать БД с таблицами и компонентами на форме. Вот я и решил сразу же проверить как в Delphi XE3 можно связать БД SQLite с таблицей, используя LiveBindings.
Итак, я создал следующую БД SQLite с названием test.db, содержащую всего одну таблицу:
Теперь, чтобы можно было работать с подключениями SQLite в design-time я скачал с официального сайта SQLite библиотеку sqlite3.dll и положил её в директорию bin к RAD Studio XE3.
Теперь создадим новое подключение в Data Explorer. Для этого заходим в Data Explorer, вызываем контекстное меню узла SQLite, выбираем «Add New Connection» и задаем имя нового соединения:
Теперь в открывшемся окне задаем параметры соединения:
Теперь, вполне возможно, что после нажатия кнопки «Test Connection» Вы получите вот такое сообщение:
Чтобы соединение прошло успешно я просто положил файл БД в папку к проекту. Результат — см. на рисунке ниже:
Соединение установлено — приступаем к работе с компонентами. Первым делом добавляем на форму компонент TSQLConnection с вкладки DBExpress и выбираем в списке свойства ConnectionName наше соединение:
Переключаем свойство Connected в значение True, убеждаемся, что все в порядке и переходим к следующему шагу — добавляем на форму компонент TBindSourceDBX.
В TBindSourceDBX нам сейчас достаточно определить одно свойство — SQLConnection в котором необходимо указать наш компонент SQLConnection1:
Кстати, как можно видеть на рисунке выше, в BindSourceDBX уже реализованы и DataSet и DataProvider и ClientDataSet для того, чтобы можно было не только просматривать данные в БД, но и редактировать их и удалять- приятная мелочь, избавляющая от лишней возни с компонентами.
Также в BindSourceDBX можно сразу задать ComandText, чтобы сразу в design-time было видно, что связывание прошло успешно. Я, например, задал такую команду:
На данном этапе работы форма проекта должна содержать всего два компонента:
И этого вполне достаточно, чтобы приступить к связыванию данных в Visual LiveBindings — все остальные необходимые компоненты добавит Помощник.
Вызываем LiveBinding Wizard, выбираем на первом шаге пункт «Link a grid with a data source» и жмем Next>>:
На втором шаге Помощник сразу предлагает нам создать новый TStringGrid для связывания — оставляем все как есть и жмем Next:
На третьем шаге мы можем либо создать новый источник данных, либо выбрать уже существующий. Т.к. у нас уже есть на форме BinSourceDBX, то его и указыванием в качестве источника:
Ну и, чтобы потом не возвращаться к компонентам, сразу добавим и навигатор:
Все. Жмем Finish. Теперь можно открыть Визуальный редактор и посмотреть на созданные связи:
Теперь переключаем у BindSourceDBX свойство Active в True и видим, что связь данных работает:
Можем запустить приложение и отредактировать/добавить/удалить записи. Если при запуске программа снова скажет, что файл с БД не найден — положите test.db к exe-файлу.
Вот и все. Без единой строчки кода, управляя только свойствами компонентов, мы связали БД SQLite с таблицей, используя возможности Visual LiveBindings в Delphi XE3.
На этом все. Для знакомство представленных примеров, полагаю, достаточно, чтобы Вы могли оценить разницу между LiveBindings в XE2 и XE3 =). Всем спасибо за внимание и удачных разработок в Delphi XE3!






























[…] уже кратко рассказывал про то как можно организовать связь с SQLite, используя Data Explorer и компоненты с вкладки dbExpress, но там […]
Все сделал по пунктам. В среде (после перевода Active в True) в Grid видны данные которыми я заполнял таблицу — т.е. все хорошо. Но при компиляции выдает ошибку о невозможности открыть базу данных. Я кидал test1.db в папку с проектом, но это не помогло. Кидал к ЕХЕ файлу — это тоже не помогло. Не могу понять в чем причина…может посоветуете что нибудь по этому поводу?
Илья Колесников, а Sqlite3.dll в папку к EXE-файлу кидали?
Подскажите, можно подключить к TTreeview через LiveBinding набор данных?
Хочу дерево формировать из БД.
Спасибо.
[…] новую RAD Studio XE3. Основными "фишками" новой версии стали Visual Live Bindings, Firemonkey 2.0. и Metropolis (до которого у меня руки так и не […]
Уважаемый Влад, спасибо за примеры. Первый пример работает без ошибок в случае, когда запись такая:
ABindSourceAdapter:=TObjectBindSourceAdapter.Create(self,Person,True);
Т.е. надо добавить
Иначе — ошибка доступа.
… надо добавить …
Прошу прощения, видимо из-за форматирования из текста выпало вот это:
____
Все равно выпадает. Добавить «знак меньше» TPerson «знак больше»,
т.е. ABindSourceAdapter:=TObjectBindSourceAdapter»знак меньше»TPerson»знак больше».Create(self,Person,True);
TPerson заключен между меньше и больше и стоит перед .Create(self,Person,True);
А есть какая — нибудь возможность при использовании TPrototypeBindSource связать объект не в OnCreateAdapter событии, а позже? Допустим, я вначале создаю программно форму, на котором находится TPrototypeBindSource , а потом передаю объект, с которым хочу связать…