Continuando a postagem do blog da semana passada sobre expressões de ligação, vamos ver como os componentes podem participar, mas criando expressões que se referem a propriedades.
Na semana passada, apresentei o mecanismo de expressão Delphi RTL na postagem do blog em https://blog.marcocantu.com/blog/2021-may-delphi-expression-engine.html . Agora vamos dar uma etapa adicional. Quero explicar como os componentes e suas propriedades podem fazer parte dessas expressões. Neste caso, não avaliamos simplesmente uma expressão, mas queremos associar duas expressões separadas em uma “ligação”.
Vinculando Dois Componentes
Em termos práticos, suponha que você tenha um formulário com SpinEdit e ProgressBar. Uma associação gerenciada permite que você forneça uma expressão de entrada (com um ou mais objetos de entrada) e uma expressão de saída (novamente com um ou mais objetos). Como você pode ver no código a seguir, cada objeto é associado à expressão fornecendo um nome, como spin1 para o componente SpinEdit1, e a expressão pode se referir ao objeto e suas propriedades, como em spin1.Value . O mesmo acontece com a saída. Você também pode especificar um conversor de saída, que omiti aqui:
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); |
Com esse código de configuração, se você chamar BindingExpression1.Evaluate, o valor do SpinEdit será copiado para a ProgressBar. Você pode fazer a mesma chamada para atualizar o valor, mas também pode abstrair o conceito, indicando para a arquitetura de ligações que a propriedade value da edição de rotação tem alterações. O sistema determinará automaticamente se há uma ou mais expressões envolvendo a propriedade e a atualizará:
1 2 3 4 |
procedure TFormBindings.SpinEdit1Change(Sender: TObject); begin TBindings.Notify(Sender, 'Value'); end; |
Essa mudança de perspectiva (um valor mudou em vez de uma expressão precisar ser recalculada) é de fundamental importância, pois abstrai totalmente o modelo de dados da IU ao qual está associado. Nós chegaremos lá, mas deixe-me mostrar a IU do aplicativo simples primeiro:
Objetos de vinculação e controles de IU
Isso é melhor explicado na segunda parte do exemplo, que contém uma caixa de edição vinculada a um objeto na memória. A classe TMyObject possui uma propriedade Name e uma Value. Veja como você pode vincular um objeto à IU:
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); |
Neste código, MyObj é um objeto da classe TMyObject. Sua propriedade Name está associada ao componente Text do edName. Novamente, a atualização da expressão atualiza a saída. Mas o objeto não deve ter conhecimento dos controles da interface do usuário ou das ligações da IU. Na verdade, tudo o que você precisa fazer para instrumentar o objeto é notificar o sistema de que o valor mudou:
1 2 3 4 5 |
procedure TMyObject.SetName(const Value: string); begin FName := Value; TBindings.Notify(self, 'Name'); end; |
Com este código, quando os dados mudam, a IU é atualizada automaticamente para refleti-los:
1 2 3 4 |
procedure TFormBindings.btnUpdateObjClick(Sender: TObject); begin myobj.Name := myobj.Name + 'Monkey'; end; |
Não estou 100% certo de como você deseja chamar os padrões implementados com ligações no Delphi, mas certamente oferece uma separação e abstração completa do modelo de dados com a visualização da interface do usuário.
Há muito mais para explorar
A seguir, podemos começar a ver como você pode trabalhar com ligações bidirecionais e como definir toda a lógica acima usando designers de componentes específicos, reduzindo o código necessário. Há muita tecnologia por trás do Visual Live Bindings, que é o destino final em potencial e é o que frequentemente discutimos. Live Bindings são legais, mas a tecnologia de binding no Delphi RTL é onde mora o poder.
Design. Code. Compile. Deploy.
Start Free Trial Upgrade Today
Free Delphi Community Edition Free C++Builder Community Edition