在Delphi XE4中无法检查的动态创建的TCheckBox

时间:2018-09-25 22:21:31

标签: delphi

我想创建一个属性编辑器,因为TValueListEditor不支持很多东西。因此,当用户输入单元格时,我使用了TStringGrid和其他控件。当我为布尔值放置TCheckBox时,动态创建的TCheckBox是不可检查的。 onClick事件处理程序不会因单击而消失(网格已裂开),TCheckBox的标题失去了不透明度。我设置它的父代并将其置于最前面。此时,我还使用了TEditTComboBox控件,它们可以正常工作。有人可以帮助以预期的方式使用它吗?

这里是重新创建情况的示例。

pas:

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Grids,
  StdCtrls;

type
  TForm1 = class(TForm)
    StringGrid1: TStringGrid;
    CheckBox1: TCheckBox;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
    procedure onCheckBoxClicked( sender_ : TObject );
  public
    { Public declarations }
    fCheckBox : TCheckBox;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.onCheckBoxClicked( sender_ : TObject );
begin
  if ( TCheckBox( sender_ ).checked ) then
    TCheckBox( sender_ ).caption := 'true'
  else
    TCheckBox( sender_ ).caption := 'false';
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  fCheckBox := TCheckBox.create( NIL );
  fCheckBox.Parent := stringGrid1;
  fCheckBox.caption := 'Dynamic checkbox';
  fCheckBox.left := 70;
  fCheckBox.top := 30;
  fCheckBox.onClick := onCheckBoxClicked;
  fCheckBox.BringToFront;
  stringgrid1.cells[1,1] := 'fgfgfgfgfgf';
  stringgrid1.cells[1,2] := 'fgfgfgfgfgf';
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  fCheckBox.Free;
end;

end.

dfm:

object Form1: TForm1
  Left = 358
  Top = 183
  Caption = 'Form1'
  ClientHeight = 601
  ClientWidth = 854
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  OnCreate = FormCreate
  OnDestroy = FormDestroy
  PixelsPerInch = 96
  TextHeight = 13
  object StringGrid1: TStringGrid
    Left = 120
    Top = 72
    Width = 320
    Height = 120
    TabOrder = 0
  end
  object CheckBox1: TCheckBox
    Left = 192
    Top = 128
    Width = 97
    Height = 17
    Caption = 'Static checkbox'
    TabOrder = 1
  end
end

1 个答案:

答案 0 :(得分:4)

这不适用于复选框,因为字符串网格拦截了WM_COMMAND消息的处理。当您单击复选框时,WM_COMMAND通知将发送到其父级-字符串网格。 “ Vcl.Grids”的TCustomGrid.WMCommand中的网格检查通知是否来自其就地编辑器,否则丢弃该消息。

您可以修改网格上消息的处理以更改行为。一种方法是派生新控件。例如

type
  TStringGrid = class(vcl.grids.TStringGrid)
  protected
    procedure WMCommand(var Message: TWMCommand); message WM_COMMAND;
  end;

  TForm1 = class(TForm)
    StringGrid1: TStringGrid;
    ....

...

procedure TStringGrid.WMCommand(var Message: TWMCommand);
var
  Control: TWinControl;
begin
  inherited;
  Control := FindControl(Message.Ctl);
  if Assigned(Control) and (Control <> InplaceEditor) then
    Control.Perform(Message.Msg, MakeWParam(Message.ItemID, Message.NotifyCode),
        Message.Ctl);
end;

然后OnClick将触发。您不需要BringToFront,它可以在同级控件之间使用。


关于不透明度,这是复选框的默认外观。您可以通过在表单本身上放置一个与标签重叠的复选框来验证这一点。