Reputation: 816
I want to create a property editor because a lot of things does not supported by TValueListEditor
. So I use a TStringGrid
and other controls placed on it when the user enter the cells. When I place a TCheckBox
for boolean values, the dynamically created TCheckBox
is uncheckable. The onClick
event handler does not fiered by the clicks (the grid fiered) and the caption of the TCheckBox
lost its opacity. I set its parent and bring it to the front. By this time I used TEdit
and TComboBox
controls as well and they work fine. Somebody can help to use it in the expected way?
Here is an example to recreate the situation.
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.
The 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
Upvotes: 3
Views: 369
Reputation: 54802
This does not work with a checkbox because the string grid intercepts processing of the WM_COMMAND
message. When you click the checkbox, a WM_COMMAND
notification is sent to its parent - which is the string grid. The grid, in TCustomGrid.WMCommand
of 'Vcl.Grids', checks if the notification is from its inplace editor and discards the message otherwise.
You can modify the processing of the message on the grid to change the behavior. One way is to derive a new control. E.g.
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;
Then the OnClick
will fire. You don't need BringToFront
, it works among sibling controls.
Regarding opacity, it's the checkbox's default appearance. You can verify this by placing a checkbox overlapping a label on the form itself.
Upvotes: 4