Это третья статья из серии «Firemonkey. От простого к сложному«. Первая и вторая статьи находятся здесь и здесь. Во второй части мы остановились на том, что рассмотрели основные свойства и методы списка FMX.TListBox. Сегодня мы продолжим разбираться со списками и посмотрим как можно связывать несколько списков между собой.
Но прежде, чем перейдем к рассмотрению темы, небольшое объявление: Embarcadero Technologies и DelphiFeeds.ru объявили о старте нового конкурса под кодовым названием «Подарки от Firemonkey!«. С условиями конкурса можете ознакомиться на страничке DelphiFeeds.ru. Участвуйте!
Некоторые вопросы по использованию LiveBindigs в Delphi XE2 я рассматривал в двух постах: «Delphi XE2. Знакомство с LiveBinding» и «Delphi XE2. LiveBindings для объектов«, так что повторяться не будем по поводу того, что такое выражения в LiveBindings, а сразу перейдем к сути вопроса «Как связывать списки в Firemonkey, используя LiveBindings?«.
Элементарщина
Начнем с самого простого. На форме расположены два списка TListBox и в определенный момент работы программы нам необходимо все строки из первого списка скопировать во второй. Элементарщина, с которой справиться даже самый неопытный, но, как известно, любую задачу (даже самую элементарную) можно решить несколькими способами. Давайте решим эту простенькую задачку с использованием LiveBindings.
Тестовой приложение будет выглядеть у нас следующим образом:
Первый список заполним в design-time, чтобы не отвлекаться на лишний код и сосредоточимся непосредственно на задаче. Теперь выполняем следующие действия по порядку:
1. Выбираем второй ListBox и в свойстве LiveBindings выбираем «New LiveBinding -> Lists -> TBindList» (создаем связь для двух списков):
На форме, как обычно, появится новый компонент под названием BindingsList1.
2. Открываем редактор компонента BindingsList1 и видим в категории Lists новый компонент связи с названием BindListLisBox21. Выбираем в редакторе этот компонент и в Object Inspector устанавливаем ему следующие свойства:
- ControlComponent = ListBox2
- SourceComponent = ListBox1
Как видите, на решение этой простейшей задачи не было затрачено ни одной строчки кода — всё решилось через использование свойств компонентов LiveBindings. Вообще, с помощью группы выражений FormatControl можно изменять не только содержимое Items, но и любых других свойств контролов. Но мы с такими задачками баловаться не будем, а лучше рассмотрим более детально свойства у TBindList (BindListLisBox21), который нам, собственно, и связал два списка — всё-таки чаще нам придётся делать более сложные связи списков нежели представленный выше пример, имеющий скорее мизерную, но исследовательскую ценность, чем практическую. Переходим ко второй части.
Свойства и методы TBindList
Так как сегодня речь идёт о списках в Firemonkey, а не конкретно о механизме LiveBindings, то рассмотрим только основные методы и свойства TBindList, которые пригодятся нам для дальнейшей работы.
Свойства AutoActivate и Active
property AutoActivate: Boolean read GetAutoActivate write SetAutoActivate default True;
Это свойство определено в классе TActivatedContainedBindComponent — прародителе TBindList и указывает на то, что компонент связи должен автоматически активироваться при запуске программы.
Если отключить это свойство в Object Inspector’е и запустить нашу программку, то второй ListBox не заполнится автоматически до тех пор пока мы не присвоим его второму свойству — Active значение True.
Свойство AutoFill
property AutoFill: Boolean read FAutoFill write SetAutoFill default True;
Это свойство отвечает за автозаполнение списка при активации компонента. Если присвоить этому свойству значение False, то впоследствии список можно будет заполнить, вызвав метод у TBindList — FillList.
Свойства ClearControlExpressions, FormatControlExpressions и FormatExpressions
Эти свойства представляет собой коллекции выражений связывания. Выражения из группы FormatControlExpressions выполняются при заполнении списка значениями, т.е. в момент вызова метода FillList перед формированием списка.
Выражения группы FormatExpressions затрагивают только элементы списка. Например, с помощью выражений из этой группы можно формировать собственные значения для элементов заполняемого списка.
Выражения ClearControlExpressions используются в момент очистки списка при вызове метода ClearList.
Метод FillList
procedure FillList;
Выполняет заполнение списка значениями согласно заданным выражениям связывания.
Метод ClearList
procedure ClearList;
Выполняет очистку списка значениями согласно заданным выражениям связывания.
Этих свойств и методом нам пока будет вполне достаточно, чтобы рассмотреть работы со списками в Firemonkey. Продолжим и рассмотрим ещё один примерчик, показывающий как связывать списки в FMX.
Связывание списков через выражения из группы FormatExpressions
В части «Элементарщина» мы с Вами воспользовались самым простым способом переноса значений из одного ListBox’а в другой — использовали группу выражений FormatControlExpressions. Но наиболее часто в работе нам будет требоваться более сложная связка элементов. Например, может потребоваться связать элементы визуального компонента TListBox с содержимым в TStrings или массиве TArray<string> и т.д. Или же надо будет при формировании нового списка проводить какие-либо изменения в тексте элемента. И здесь уже группа выражений FormatControlExpressions нам вряд ли сильно поможет. Необходимо будет воспользоваться выражениями их FormatExpressions. И как это сделать мы разберемся прямо сейчас.
Итак, задача №2: Необходимо вывести в список ListBox1 содержимое списка TStringsList, используя возможности LiveBindings.
Для решения этой задачки нам необходимо вернуться немного назад и вспомнить про статью «Delphi XE2. LiveBindings для объектов.» Всё, что от нас требуется — это использовать вместо TBindExpression объект TBindList. Пройдемся опять по всем пунктам решения.
1. Создаем наш список TStringList.
Так как у нас уже есть от предыдущей задачи список ListBox1 с некоторым количеством элементов, то им и воспользуемся для формирования нашего TStringList:
type TForm10 = class(TForm) private FStrings: TStrings; public end; [...] procedure TForm10.FormCreate(Sender: TObject); begin FStrings:=TStringList.Create; FStrings.Assign(ListBox1.Items); end;
2. Бросаем на форму компонент TBindScope и пишем обработчик кнопки заполнения списка
Обработчик будет выглядеть следующим образом:
procedure TForm10.Button1Click(Sender: TObject); var BindList:TBindList; begin try BindScope1.DataObject:=FStrings; BindList:=TBindList.Create(nil); BindList.SourceComponent:=BindScope1; BindList.ControlComponent:=ListBox2; with BindList.FormatExpressions.AddExpression do begin ControlExpression:='Text'; SourceExpression:='Current'; end; BindList.FillList; finally BindList.Free end; end;
Рассмотрим, что здесь мы здесь написали. Вначале мы указали для компонента BindScope объект из которого мы будем получать данные — FStrings: TStringList.
Затем, мы создали новый объект TBindList для связи двух списков и определили в нем компонент-пиремник и -исходник. А дальше мы, используя метод AddExpression добавили новое выражение связи для элементов списка и внесли это выражение в группу FormatExpression:
with BindList.FormatExpressions.AddExpression do begin ControlExpression:='Text'; SourceExpression:='Current'; end;
Здесь Current в выражении SourceExpression указывает на текущий элемент в списке, а Text — свойство элемента списка TListBoxItem. И в конце мы вызвали FillList для заполнения списка и очистили память от BindList.
На этом задача решена =) Можете запустить программку и убедиться, что ListBox заполняется значениями. Аналогичным образом заполняется ListBox из из других перечисляемых объектов, например из массивов, списков объектов и т.д.
Вот, пожалуй, кратко и немного скомкано про работу со списками в Firemonkey. Для рассмотрения основ работы с Firemonkey, по-моему должно хватить. В дальнейшем мы, скорее всего, ещё раз вернемся к работе со списками в fmx, но уже более основательно и подробно. А пока перейдем к следующим компонентам и в следующий раз рассмотрим работу с таблицами.
[…] Firemonkey. От простого к сложному #3. Компоненты FMX: списки (п… […]
Извините елси малях офтоп, а вот делаю приложение в FireMonkey, компоненты доступа к БД присутствуют, соединение есть… а dbgrid, например, нет. Нарыл разные советы по использованию связки со StringGrid -это реально? норм в дизайнтайме не поработать с БД? без этих танцев с бубном даже в рилатайме?
в FireMonkey есть только TGrid и TStringGrid. Соответственно и работа с БД строится на этих контролах…ну или других каких угодно. При этом можно (и нужно) для связи визуальных контролов и БД использовать LiveBindings. Простенький пример как это делается есть в Samples
Неудобняк. Видать для писанину под БД придется оставаться на VCL…
т.е. для писанинЫ, очепятался
такой вопрос, а есть ли где-нибудь уже готовые стили firemonkey, чтобы можно было скачать и загрузить в проект?
mops пишет:
28 Дек 2011 в 1:10 пп
такой вопрос, а есть ли где-нибудь уже готовые стили firemonkey, чтобы можно было скачать и загрузить в проект?
Может не догнал, поясните пожалуйста, что Вы имеете ввиду под готовыми стилями FM? есть демо у них, есть понятие vcl-style, я заранее прошу прощения, но я реально не понял вопроса..
я про firemonkey приложения. там же можно редактировать «стили» компонентов. т.е. когда я жму по компоненту правой кнопкой и в меню выбираю «edit custom style» или «edit default style». и в открывшемся редакторе изменяю что мне нужно. так вот, эти стили можно сохранять и загружать. вот про них я то и спрашивал )
mops, я в стилях пока глубоко не копался, поэтому боюсь, что где-то могу соврать в ответе. Гляньте вот эту вот тулзу http://www.delphilab.ru/content/view/345/1/ судя по описанию меняет стили и позволяет загружать готовые. Может быть по исходникам будет видно как и что работает
[…] От простого к сложному". На повестке дня, как и было сказано в последней статье цикла, основы работы с таблицами в […]
Реализовал загрузку данных из файла в коллекцию. Для отображения по старинке использую for… Нутром чую, что можно LiveBinding, но мыслей не хватает пока как… Допустим элемент коллекции содержит ФИО, а в ListboxItem, в соответствии со стилем, вывод в три label. Какие будут идеи?
Vlad, понятно, что пример слишком элементарный, но иной раз хочется сказать, что не везде нужно пихать все самое-самое современное (я о LiveBindings/DataBindings)… Просто наблюдаю много-много лет за технологиями и диву даюсь — если прикрутили какую-то фичу разработчики IDE, то все начинают в дело и не в дело ее пихать куда ни попадя. Надо примеры брать, показывающие необходимость использования тех или иных нововведений, а-то даже сейчас (в ходу версия не XE2, а 10.4) гораздо удобнее Ваш же пример написать так: procedure TMainForm.Button1Click(Sender: TObject); var i: integer; begin ListBox2.Items.Clear; for I := 0 to FStrings.Count-1 do ListBox2.Items.Add(FStrings[i]); end; …и… Подробнее »