How to write live binding expression that control TEdit.PasswordChar based on TCheckBox.Checked?

孤街醉人 提交于 2019-12-22 22:26:05

问题


I have 2 controls on a form, TCheckBox and TEdit.

I want to use Live Binding to perform this:

  1. When TCheckBox.Checked = True, set TEdit.PasswordChar = *
  2. When TCheckBox.Checked = False, set TEdit.PasswordChar = #0

How may I write ControlExpression to achieve this? It would be great if I can avoid register custom method.


回答1:


Here's a simple example. I couldn't find a boolean expression evaluator so I registered a new one, and also a string-to-char converter (seems to be missing, too).

The form:

object Form1: TForm1
  Left = 0
  Top = 0
  Caption = 'Form1'
  ClientHeight = 282
  ClientWidth = 418
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
  object CheckBox1: TCheckBox
    Left = 24
    Top = 24
    Width = 97
    Height = 17
    Caption = 'CheckBox1'
    TabOrder = 0
    OnClick = CheckBox1Click
  end
  object Edit1: TEdit
    Left = 24
    Top = 56
    Width = 121
    Height = 21
    TabOrder = 1
    Text = 'Edit1'
  end
  object BindingsList1: TBindingsList
    Methods = <>
    OutputConverters = <>
    UseAppManager = True
    Left = 212
    Top = 13
    object BindExpression1: TBindExpression
      Category = 'Binding Expressions'
      ControlComponent = Edit1
      SourceComponent = CheckBox1
      SourceExpression = 'iif(Checked, '#39'*'#39', '#39#39')'
      ControlExpression = 'PasswordChar'
      NotifyOutputs = True
      Direction = dirSourceToControl
    end
  end
end

and the code:

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Data.Bind.EngExt, Vcl.Bind.DBEngExt, System.Rtti,
  Vcl.Bind.Editors, Data.Bind.Components, System.Bindings.Outputs;

type
  TForm1 = class(TForm)
    CheckBox1: TCheckBox;
    Edit1: TEdit;
    BindingsList1: TBindingsList;
    BindExpression1: TBindExpression;
    procedure CheckBox1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses
  System.TypInfo,
  System.Bindings.EvalProtocol,
  System.Bindings.Methods;

resourcestring
  sIifArgError = 'Expected three variables for Iif() call';
  sIifExpectedBoolean = 'First argument to Iif() must be a boolean';

function MakeIif: IInvokable;
begin
  Result := MakeInvokable(
    function(Args: TArray<IValue>): IValue
    var
      V: IValue;
      B: Boolean;
    begin
      if Length(Args) <> 3 then
        raise EEvaluatorError.Create(sIifArgError);
      V := Args[0];
      if (V.GetType^.Kind <> tkEnumeration) or (V.GetType^.Name <> 'Boolean') then
        raise EEvaluatorError.Create(sIifExpectedBoolean);

      B := V.GetValue.AsBoolean;
      if B then
        Result := TValueWrapper.Create(Args[1].GetValue)
      else
        Result := TValueWrapper.Create(Args[2].Getvalue);
    end
  );
end;

procedure TForm1.CheckBox1Click(Sender: TObject);
begin
  BindingsList1.Notify(CheckBox1, 'Checked');
end;

initialization
  TBindingMethodsFactory.RegisterMethod(TMethodDescription.Create(MakeIif, 'iif', 'iif', '', True, '', nil));
  TValueRefConverterFactory.RegisterConversion(TypeInfo(string), TypeInfo(Char),
    TConverterDescription.Create(
      procedure(const I: TValue; var O: TValue)
      var
        S: string;
      begin
        S := I.AsString;
        if Length(S) = 1 then
          O := S[1]
        else
          O := #0;
      end,
      'StringToChar', 'StringToChar', '', True, '', nil));

finalization
  TValueRefConverterFactory.UnRegisterConversion('StringToChar');
  TBindingMethodsFactory.UnRegisterMethod('iif');

end.


来源:https://stackoverflow.com/questions/11573434/how-to-write-live-binding-expression-that-control-tedit-passwordchar-based-on-tc

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!