4

TCheckBox最初の列の文字列グリッド ( )にチェックボックス ( ) を配置TStringGridしています。チェックボックスは正しく表示され、正しく配置され、マウスをホバーすると光って反応します。ただし、それらをクリックしてもトグルしません。それらはクリックに反応して強調表示されますが、最終的に実際のCheckedプロパティは変更されません。OnClickさらに不可解なのは、これらの値がいったんそこにあると変更するコードがなく、これらのチェックボックスにイベントが割り当てられていないことです。また、これらのチェックボックスをデフォルトでオフにしていますが、表示されるとチェックされます

チェックボックスは、リストに追加される各レコードとともに作成され、チェックボックスが配置されるセル内のオブジェクトに割り当てられたレコード ポインター内で参照されます。

セルの強調表示のための文字列グリッドのハック:

type
  THackStringGrid = class(TStringGrid); //used later...

チェックボックスを含むレコード:

  PImageLink = ^TImageLink;
  TImageLink = record
    ...other stuff...
    Checkbox: TCheckbox;
    ShowCheckbox: Bool;
  end;

チェックボックスの作成/破棄:

function NewImageLink(const AFilename: String): PImageLink;
begin
  Result:= New(PImageLink);
  ...other stuff...
  Result.Checkbox:= TCheckbox.Create(nil);
  Result.Checkbox.Caption:= '';
end;

procedure DestroyImageLink(AImageLink: PImageLink);
begin
  AImageLink.Checkbox.Free;
  Dispose(AImageLink);
end;

行をグリッドに追加:

//...after clearing grid...
//L = TStringList of original filenames
if L.Count > 0 then
  lstFiles.RowCount:= L.Count + 1
else
  lstFiles.RowCount:= 2; //in case there are no records
for X := 0 to L.Count - 1 do begin
  S:= L[X];
  Link:= NewImageLink(S); //also creates checkbox
  Link.Checkbox.Parent:= lstFiles;
  Link.Checkbox.Visible:= Link.ShowCheckbox;
  Link.Checkbox.Checked:= False;
  Link.Checkbox.BringToFront;
  lstFiles.Objects[0,X+1]:= Pointer(Link);
  lstFiles.Cells[1, X+1]:= S;
end;

グリッドの OnDrawCell イベント ハンドラ:

procedure TfrmMain.lstFilesDrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
var
  Link: PImageLink;
  CR: TRect;
begin
  if (ARow > 0) and (ACol = 0) then begin
    Link:= PImageLink(lstFiles.Objects[0,ARow]); //Get record pointer
    CR:= lstFiles.CellRect(0, ARow); //Get cell rect
    Link.Checkbox.Width:= Link.Checkbox.Height;
    Link.Checkbox.Left:= CR.Left + (CR.Width div 2) - (Link.Checkbox.Width div 2);
    Link.Checkbox.Top:= CR.Top;
    if not Link.Checkbox.Visible then begin
      lstFiles.Canvas.Brush.Color:= lstFiles.Color;
      lstFiles.Canvas.Brush.Style:= bsSolid;
      lstFiles.Canvas.Pen.Style:= psClear;
      lstFiles.Canvas.FillRect(CR);
      if lstFiles.Row = ARow then
        THackStringGrid(lstFiles).DrawCellHighlight(CR, State, ACol, ARow);
    end;
  end;
end;

クリックするとこんな感じ・・・

マウスクリックに反応するが変わらない

何が原因でしょうか? Checked私のコードのどこでもプロパティを変更することは絶対にありません。チェックボックスをグリッドに配置すると、チェックボックス自体が奇妙な動作をすることがあります。

編集

簡単なテストをTCheckBox行い、フォームにレギュラーを配置しました。正常にチェック/チェックを外します。次に、フォームのOnShowイベントで、チェックボックスParentをこのグリッドに変更しました。今回は、クリックしてもトグルせず、同じ動作になります。そのため、TCheckBox別のコントロールを親に持つと a が正しく反応しないようです。これを克服する方法は?

4

3 に答える 3

9

TStringGridWMCommandハンドラーは、子コントロールがメッセージを処理することを許可しません(InplaceEditを除く)。

したがって、一部の人々がアドバイスしているように、たとえば、挿入されたクラス(PeterBelowによるコードに基づく)を使用したり、手でコントロールを描画したりできます。介在するクラスのコードは次のとおりです。

uses
  Grids;

type
  TStringGrid = class(Grids.TStringGrid)
  private
    procedure WMCommand(var AMessage: TWMCommand); message WM_COMMAND;
  end;

implementation

procedure TStringGrid.WMCommand(var AMessage: TWMCommand);
begin
  if EditorMode and (AMessage.Ctl = InplaceEditor.Handle) then
    inherited
  else
  if AMessage.Ctl <> 0 then
  begin
    AMessage.Result := SendMessage(AMessage.Ctl, CN_COMMAND,
      TMessage(AMessage).WParam, TMessage(AMessage).LParam);
  end;
end;
于 2012-07-30T14:53:20.010 に答える
3

Delphi7では、少なくとも私はこれを行います:

fChecked[]セルにチェックボックスを描画し、各行のチェックボックスの状態を示すブール値の配列 (ここでは ) と同期させる必要があります。次に、のDrawCell部分でTStringGrid

var
 cbstate: integer;
begin
...
if fChecked[Arow] then cbState:=DFCS_CHECKED else cbState:=DFCS_BUTTONCHECK;
DrawFrameControl(StringGrid.canvas.handle, Rect, DFC_BUTTON, cbState);
...
end;

スペースバーに応答するチェックボックスを取得するには、KeyDownイベントを使用して再描画を強制します。

if (Key = VK_SPACE) And (col=ColWithCheckBox) then begin
  fChecked[row]:=not fChecked[row];
  StringGrid.Invalidate;
  key:=0;
end;

メソッドにも同様のアプローチが必要ですOnClick

于 2012-07-30T11:59:46.010 に答える
0
  1. grid の代わりに toReportMode (TListView エミュレート) モードで VirtualTreeView を使用できますか?

  2. NexusDB や TClientDataSet などのメモリ内テーブルで TDBGrid を使用できますか?

  3. 醜いアプローチは、WinDings やhttp://fortawesome.github.com/Font-Awesomeなどのカスタム フォントを使用した文字のようなチェックボックスを表示することです。

後者は実装が最も簡単ですが、見にくく、維持するのが最も柔軟性に欠けます。ビジネス ロジックが VCL イベント ハンドラに混在します。

于 2012-07-30T10:39:14.980 に答える