Продолжая сообщение в блоге на прошлой неделе о выражениях привязки, давайте посмотрим, как компоненты могут участвовать, но создавать выражения, которые ссылаются на свойства.
На прошлой неделе я представил движок выражений Delphi RTL в сообщении блога по адресу https://blog.marcocantu.com/blog/2021-may-delphi-expression-engine.html . Теперь сделаем дополнительный шаг. Я хочу объяснить, как компоненты и их свойства могут быть частью этих выражений. В этом случае мы не просто оцениваем выражение, но хотим связать два отдельных выражения в «привязку».
Связывание двух компонентов
На практике предположим, что у вас есть форма со SpinEdit и ProgressBar. Управляемая привязка позволяет вам предоставить входное выражение (с одним или несколькими входными объектами) и выходное выражение (снова с одним или несколькими объектами). Как вы можете видеть в приведенном ниже коде, каждый объект связан с выражением, предоставляющим имя, например spin1 для компонента SpinEdit1 , и выражение может относиться к объекту и его свойствам, как в spin1.Value . То же самое и с выходом. Вы также можете указать выходной преобразователь, который я здесь пропустил:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
BindingExpression1 := TBindings.CreateManagedBinding( { inputs } [TBindings.CreateAssociationScope([ Associate(SpinEdit1, 'spin1') ])], 'spin1.Value', { outputs } [TBindings.CreateAssociationScope([ Associate(ProgressBar1, 'progress') ])], 'progress.Position', {OutputConverter} nil); |
С этим кодом конфигурации, если вы вызовете BindingExpression1.Evaluate, значение SpinEdit будет скопировано в ProgressBar. Вы можете сделать тот же вызов, чтобы обновить значение, но вы также можете абстрагироваться от концепции, указав архитектуре привязок, что свойство value изменения прокрутки изменилось. Система автоматически определит, есть ли одно или несколько выражений, связанных со свойством, и обновит его:
1 2 3 4 |
procedure TFormBindings.SpinEdit1Change(Sender: TObject); begin TBindings.Notify(Sender, 'Value'); end; |
Это изменение перспективы (значение изменилось, а не нужно пересчитывать выражение) имеет фундаментальное значение, поскольку оно полностью абстрагирует модель данных от пользовательского интерфейса, с которым она связана. Мы доберемся до этого, но сначала позвольте мне показать простой пользовательский интерфейс приложения:
Привязка объектов и элементов управления пользовательского интерфейса
Это лучше объяснить во второй части примера, где поле редактирования привязано к объекту в памяти. Класс TMyObject имеет свойства Name и Value. Вот как вы можете привязать объект к пользовательскому интерфейсу:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
BindingExpressionObj := TBindings.CreateManagedBinding( { inputs } [TBindings.CreateAssociationScope([ Associate(MyObj, 'obj') ])], 'obj.Name', { outputs } [TBindings.CreateAssociationScope([ Associate(edName, 'edit') ])], 'edit.Text', {OutputConverter} nil); |
В этом коде MyObj является объектом класса TMyObject. Его свойство Name связано с компонентом edName Text. Опять же, обновление выражения обновляет вывод. Но объект не должен знать элементы управления пользовательского интерфейса или привязки пользовательского интерфейса. Фактически, все, что вам нужно сделать для инструментирования объекта, — это уведомить систему об изменении значения:
1 2 3 4 5 |
procedure TMyObject.SetName(const Value: string); begin FName := Value; TBindings.Notify(self, 'Name'); end; |
С помощью этого кода при изменении данных пользовательский интерфейс обновляется автоматически, чтобы отразить это:
1 2 3 4 |
procedure TFormBindings.btnUpdateObjClick(Sender: TObject); begin myobj.Name := myobj.Name + 'Monkey'; end; |
Я не уверен на 100%, как вы хотите вызывать шаблоны, реализованные с привязками в Delphi, но он, безусловно, предлагает полное разделение и абстракцию модели данных с представлением пользовательского интерфейса.
Есть еще много чего исследовать
Затем мы можем начать изучать, как вы можете работать с двунаправленными привязками и как вы можете определить всю приведенную выше логику с помощью конкретных конструкторов компонентов, уменьшив необходимый код. В основе Visual Live Bindings лежит множество технологий, которые являются потенциальным конечным пунктом назначения и о чем мы часто говорим. Живые привязки хороши, но технология привязки в Delphi RTL — это то, где живет сила.
Design. Code. Compile. Deploy.
Start Free Trial Upgrade Today
Free Delphi Community Edition Free C++Builder Community Edition