Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 如何基于TCheckBox.Checked编写控制TEdit.PasswordChar的活动绑定表达式?_Delphi_Livebindings - Fatal编程技术网

Delphi 如何基于TCheckBox.Checked编写控制TEdit.PasswordChar的活动绑定表达式?

Delphi 如何基于TCheckBox.Checked编写控制TEdit.PasswordChar的活动绑定表达式?,delphi,livebindings,Delphi,Livebindings,我在表单上有两个控件,TCheckBox和TEdit 我想使用Live Binding执行以下操作: 当TCheckBox.Checked=True时,设置TEdit.PasswordChar=* 当TCheckBox.Checked=False时,设置TEdit.PasswordChar=#0 如何编写ControlExpression来实现这一点?如果我可以避免注册自定义方法,那就太好了。这里有一个简单的例子。我找不到布尔表达式计算器,所以我注册了一个新的计算器,还有一个字符串到字符的转换器

我在表单上有两个控件,TCheckBox和TEdit

我想使用Live Binding执行以下操作:

  • 当TCheckBox.Checked=True时,设置TEdit.PasswordChar=*
  • 当TCheckBox.Checked=False时,设置TEdit.PasswordChar=#0

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

    这里有一个简单的例子。我找不到布尔表达式计算器,所以我注册了一个新的计算器,还有一个字符串到字符的转换器(似乎也丢失了)

    表格:

    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
    
    对象格式1:t格式1
    左=0
    Top=0
    标题='Form1'
    ClientHeight=282
    ClientWidth=418
    颜色=clBtnFace
    Font.Charset=默认字符集
    Font.Color=clWindowText
    字体高度=-11
    Font.Name='Tahoma'
    Font.Style=[]
    OldCreateOrder=False
    PixelsPerInch=96
    text高度=13
    对象复选框1:t复选框
    左=24
    Top=24
    宽度=97
    高度=17
    标题='CheckBox1'
    TabOrder=0
    OnClick=CheckBox1Click
    结束
    对象Edit1:TEdit
    左=24
    Top=56
    宽度=121
    高度=21
    TabOrder=1
    Text='Edit1'
    结束
    对象绑定列表1:TBindingsList
    方法=
    输出转换器=
    UseAppManager=True
    左=212
    Top=13
    对象BindExpression1:TBindExpression
    类别='绑定表达式'
    ControlComponent=Edit1
    SourceComponent=CheckBox1
    SourceExpression='iif(选中,#39'*'#39','#39#39')'
    ControlExpression='PasswordChar'
    NotifyOutputs=True
    方向=方向源控制
    结束
    结束
    结束
    
    以及守则:

    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.
    
    单元1;
    接口
    使用
    Winapi.Windows、Winapi.Messages、System.SysUtils、System.Variants、System.Classes、Vcl.Graphics、,
    Vcl.控件、Vcl.窗体、Vcl.对话框、Vcl.StdCtrls、Data.Bind.EngExt、Vcl.Bind.DBEngExt、System.Rtti、,
    Vcl.Bind.Editors、Data.Bind.Components、System.Bindings.Outputs;
    类型
    TForm1=类(TForm)
    复选框1:t复选框;
    编辑1:TEdit;
    绑定列表1:t绑定列表;
    BindExpression1:TBindExpression;
    程序检查框1单击(发送方:ToObject);
    私有的
    {私有声明}
    公众的
    {公开声明}
    结束;
    变量
    表1:TForm1;
    实施
    {$R*.dfm}
    使用
    System.TypInfo,
    System.Bindings.EvalProtocol,
    System.Bindings.Methods;
    资源字符串
    sIifArgError='Iif()调用需要三个变量';
    sIifExpectedBoolean='Iif()的第一个参数必须是布尔值';
    函数MakeIif:IInvokable;
    开始
    结果:=MakeInvokable(
    函数(Args:TArray):IValue
    变量
    五:伊瓦鲁;;
    B:布尔型;
    开始
    如果长度(Args)为3,则
    提高EEvaluatorError.Create(sIifArgError);
    V:=Args[0];
    如果是(V.GetType^.Kind tkEnumeration)或(V.GetType^.Name'Boolean'),则
    提高EEEvaluatorError.Create(sIifExpectedBoolean);
    B:=V.GetValue.AsBoolean;
    如果B那么
    结果:=TValueWrapper.Create(参数[1].GetValue)
    其他的
    结果:=TValueWrapper.Create(Args[2].Getvalue);
    结束
    );
    结束;
    程序TForm1.复选框1单击(发送方:TObject);
    开始
    BindingsList1.Notify(CheckBox1,“Checked”);
    结束;
    初始化
    TBindingMethodsFactory.RegisterMethod(TMethodDescription.Create(MakeIif,'iif','iif','iif','',True','nil));
    TValueRefConverterFactory.RegisterConversion(类型信息(字符串)、类型信息(字符),
    TConverterDescription.Create(
    过程(常数I:TValue;变量O:TValue)
    变量
    S:字符串;
    开始
    S:=I.AsString;
    如果长度=1,则
    O:=S[1]
    其他的
    O:=#0;
    完,,
    “StringToChar”、“StringToChar”、“True”、“nil”);
    定稿
    TValueRefConverterFactory.UnRegisterConversion('StringToChar');
    TBindingMethodsFactory.UnRegisterMethod('iif');
    结束。
    
    最好将复选框指定给操作,并在执行时编写“本机”代码。也许在某些情况下使用实时绑定是有原因的,但它们肯定不是为懒惰的程序员准备的;)这个例子显示了livebinding设计是多么荒谬。编写大量代码,但仍然必须实现OnClick事件。您不必实现
    OnClick
    事件处理程序,如图所示。还有其他可能性(例如,
    Application.OnIdle
    ,使用通用代码自动重新评估所有活动绑定,类似于操作),甚至更糟。组件应该具有绑定意识,理论上是这样的,因为它们支持在处理afaik数据集时使用的bindlink。但它不能正确处理组件到组件或组件到简单数据对象的绑定。同意,更好的方法是在源组件更改时自动计算所有绑定。也许这可以通过某种RTTI钩子来完成。编写OnChange事件处理程序是可以的,因为它可能有很大的机会被许多控件共享。绑定方法促进了代码重用,并可能大大减少.pas文件中的代码,从而将重点放在UI控件交互以外的逻辑上。