уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.
Эта статья писалась, когда актуальной была Delphi XE2. На данный момент есть более новые версии Delphi и часть информации, изложенной в этой статье может быть уже не актуальной.

Это третья статья из серии «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
Свойства компонента BindListLisBox21 в итоге будут выглядеть так, как показано на рисунке ниже:
3. Открываем редактор выражений для BindListLisBox21  (делаем двойной щелчок мышкой по его имени в открытом редакторе BindingsList1). В этом редакторе содержится три группы выражение: FormatControl, ClearControl и Format. Нам сейчас требуется выражение в группе FormatControl. Выбираем в списке слева эту категорию и жмем Insert или кнопку «Add Expression» чтобы создать новое выражение связи. Пишем в строке «Control Expression for LisBox2» всего 5 символов: ITEMS. Тоже самое пишем и для источника данных.
4. Сохраняем выражение, выходим из редакторов, жмем F9 и радуемся результату — всё, что находилось в ListBox1 сразу после запуска программы скопировалось в ListBox2.

Как видите, на решение этой простейшей задачи не было затрачено ни одной строчки кода — всё решилось через использование свойств компонентов 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, но уже более основательно и подробно. А пока перейдем к следующим компонентам и в следующий раз рассмотрим работу с таблицами.

0 0 голоса
Рейтинг статьи
уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.
Подписаться
Уведомить о
12 Комментарий
Межтекстовые Отзывы
Посмотреть все комментарии
trackback

[…] Firemonkey. От простого к сложному #3. Компоненты FMX: списки (п… […]

Дима
Дима
12/12/2011 22:09

Извините елси малях офтоп, а вот делаю приложение в FireMonkey, компоненты доступа к БД присутствуют, соединение есть… а dbgrid, например, нет. Нарыл разные советы по использованию связки со StringGrid -это реально? норм в дизайнтайме не поработать с БД? без этих танцев с бубном даже в рилатайме?

zdm
zdm
27/12/2011 16:07

Неудобняк. Видать для писанину под БД придется оставаться на VCL…

zdm
zdm
27/12/2011 16:08

т.е. для писанинЫ, очепятался

mops
mops
28/12/2011 13:10

такой вопрос, а есть ли где-нибудь уже готовые стили firemonkey, чтобы можно было скачать и загрузить в проект?

zdm
zdm
02/01/2012 20:39

mops пишет:
28 Дек 2011 в 1:10 пп

такой вопрос, а есть ли где-нибудь уже готовые стили firemonkey, чтобы можно было скачать и загрузить в проект?
Может не догнал, поясните пожалуйста, что Вы имеете ввиду под готовыми стилями FM? есть демо у них, есть понятие vcl-style, я заранее прошу прощения, но я реально не понял вопроса..

mops
mops
05/01/2012 01:34

я про firemonkey приложения. там же можно редактировать «стили» компонентов. т.е. когда я жму по компоненту правой кнопкой и в меню выбираю «edit custom style» или «edit default style». и в открывшемся редакторе изменяю что мне нужно. так вот, эти стили можно сохранять и загружать. вот про них я то и спрашивал )

trackback

[…] От простого к сложному". На повестке дня, как и было сказано в последней статье цикла, основы работы с таблицами в […]

Alexander
Alexander
08/12/2014 10:25

Реализовал загрузку данных из файла в коллекцию. Для отображения по старинке использую for… Нутром чую, что можно LiveBinding, но мыслей не хватает пока как… Допустим элемент коллекции содержит ФИО, а в ListboxItem, в соответствии со стилем, вывод в три label. Какие будут идеи?

Дмитрий Соколов
Дмитрий Соколов
24/04/2021 03:15

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; …и… Подробнее »