delphi – 为什么TStringGrid的子控件不能正常工作?
发布时间:2020-12-15 09:40:27 所属栏目:大数据 来源:网络整理
导读:我将复选框(TCheckBox)放在第一列的字符串网格(TStringGrid)中.复选框显示正常,正确定位,并在鼠标悬停时通过发光响应鼠标.但是,当我点击它们时,它们不会切换.他们对点击作出反应并突出显示,但最后,实际的Checked属性不会改变.更令人费解的是,我没有任何代码
我将复选框(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; Grid的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事件中,我将Checkbox的Parent更改为此网格.这一次,我得到了相同的行为,而不是在点击时切换.因此,当它有另一个控件作为其父控件时,似乎TCheckBox没有正确反应.怎么克服这个? 解决方法
TStringGrid的WMCommand处理程序不允许子控件处理消息(InplaceEdit除外).
所以你可以使用例如一些人建议,插入一个类(基于code by Peter Below)或手工绘制控件.这是插入类的代码: 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; (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |