设置 TStringGrid 上选定行的背景颜色
我有一个 TStringGrid,其中所选行(最多 1,无多选)应始终具有不同的背景颜色。
我将 DefaultDrawing 属性设置为 false,并为 OnDrawCell 事件提供一个方法,如下所示 - 但它不起作用。我什至无法准确描述它是如何不起作用的;我想如果我能的话我就已经解决了这个问题。可以说,它不是具有相同背景颜色的完整行,而是一个大杂烩。多行具有一些“选定”颜色的单元格,并且并非选定行的所有单元格都具有选定的颜色。
请注意,我将单元格的行与 strnggrid 的行进行了比较;我无法检查所选单元格状态,因为仅选择了所选行的单元格。
procedure TForm1.DatabaseNamesStringGridDrawCell(Sender: TObject;
ACol, ARow: Integer;
Rect: TRect;
State: TGridDrawState);
var cellText :String;
begin
if gdFixed in State then
DatabaseNamesStringGrid.Canvas.Brush.Color := clBtnFace
else
if ARow = DatabaseNamesStringGrid.Row then
DatabaseNamesStringGrid.Canvas.Brush.Color := clAqua
else
DatabaseNamesStringGrid.Canvas.Brush.Color := clWhite;
DatabaseNamesStringGrid.Canvas.FillRect(Rect);
cellText := DatabaseNamesStringGrid.Cells[ACol, ARow];
DatabaseNamesStringGrid.Canvas.TextOut(Rect.Left + 2, Rect.Top + 2, cellText);
end;
I have a TStringGrid where the selected row (max 1, no multi-select) should always have a different background colo(u)r.
I set the DefaultDrawing property to false, and provide a method for the OnDrawCell event, shown below - but it is not working. I can't even describe exactly how it is not working; I supect that if I could I would already have solved the problem. Suffice it to say that instead of having complete rows all with the same background colour it is a mish-mash. Muliple rows have some cells of the "Selected" colour and not all cells of the cselected row have the selected colour.
Note that I compare the cell's row with the strnggrid's row; I can't check the cell state for selected since only cell of the selected row is selected.
procedure TForm1.DatabaseNamesStringGridDrawCell(Sender: TObject;
ACol, ARow: Integer;
Rect: TRect;
State: TGridDrawState);
var cellText :String;
begin
if gdFixed in State then
DatabaseNamesStringGrid.Canvas.Brush.Color := clBtnFace
else
if ARow = DatabaseNamesStringGrid.Row then
DatabaseNamesStringGrid.Canvas.Brush.Color := clAqua
else
DatabaseNamesStringGrid.Canvas.Brush.Color := clWhite;
DatabaseNamesStringGrid.Canvas.FillRect(Rect);
cellText := DatabaseNamesStringGrid.Cells[ACol, ARow];
DatabaseNamesStringGrid.Canvas.TextOut(Rect.Left + 2, Rect.Top + 2, cellText);
end;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
如果您尝试用不同的颜色绘制选定的行或单元格,则必须检查
state
变量中的gdSelected
值。if you are trying of paint the selected row or cell with a different color you must check for the
gdSelected
value in thestate
var.您启用了运行时主题吗?运行时主题会覆盖您尝试为 Windows Vista 及更高版本强制实施的任何配色方案。
Do you have run-time themes enabled? Run-time themes override any colour scheme you try to enforce for Windows Vista and up.
这对我有用
刷新网格
注意:有一点延迟,但在其他方面效果很好。
(用于德尔福XE2)
This works for me
Refresh the grid
Note: Has a little latency, but otherwise works great.
(Used in Delphi XE2)
当在字符串网格中选择新单元格时,只有前一个和新选择的单元格才会失效。因此,前一行和新行的剩余单元格不会重新绘制,从而达到您所描述的效果。
一种解决方法是为受影响的行调用 InvalidateRow,但这是受保护的方法,您必须找到一种方法从 OnSelectCell 事件处理程序访问此方法。根据您的 Delphi 版本,有不同的方法可以实现这一点。
最干净的方法是从 TStringGrid 派生,但在大多数情况下这是不可行的。在较新的 Delphi 版本中,您可以使用类助手来实现此目的。否则,您必须依赖通常的受保护的黑客。
When a new cell is selected in a stringgrid only the previous and the new selected cell are invalidated. Thus the remaining cells of the previous and new row are not redrawn, giving the effect you describe.
One workaround would be to call InvalidateRow for both affected rows, but this is a protected method and you have to find a way to reach this method from an OnSelectCell event handler. Depending on your Delphi version there are different ways to accomplish that.
The cleanest way would be to derive from TStringGrid, but in most cases this is not feasible. With a newer Delphi version you can use a class helper to achieve this. Otherwise you have to rely on the usual protected hack.