如何编写基于TCheckBox.Checked控制TEdit.PasswordChar的实时绑定表达式? [英] How to write live binding expression that control TEdit.PasswordChar based on TCheckBox.Checked?

查看:100
本文介绍了如何编写基于TCheckBox.Checked控制TEdit.PasswordChar的实时绑定表达式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在窗体上有2个控件,TCheckBox和TEdit。

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

我想使用Live Binding来执行此操作:

I want to use Live Binding to perform this:


  1. 当TCheckBox.Checked = True时,设置TEdit.PasswordChar = *

  2. 当TCheckBox.Checked = False时,设置TEdit.PasswordChar =#0

我该如何编写ControlExpression来实现这一目标?如果可以避免注册自定义方法,那就太好了。

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

推荐答案

这里有一个简单的示例。我找不到布尔表达式评估器,所以我注册了一个新的布尔评估器,也注册了一个字符串到字符转换器(似乎也缺少了)。

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形式:

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

代码:

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.

这篇关于如何编写基于TCheckBox.Checked控制TEdit.PasswordChar的实时绑定表达式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆