2016-07-09 33 views
2

我有一个TStringGrid其单元格使用OnDrawCell事件获得自定义背景颜色。现在我想直观地将每一行延伸到网格的右端ClientRect,即删除没有列的空白处。如何在TStringGrid.OnDrawCell中绘制单元格外部?

我考虑使用一个额外的“幻像”列并不断调整它的ColWidth,但是这种破解不能很好地处理网格有点尴尬的垂直滚动行为。我的首选解决方案是简单地绘制该区域。

计算相关矩形很容易,但是我对它的绘制会立即被擦除。我禁用了DefaultDrawing并删除了所有选项goFixedVertLine,goFixedHorzLine,goVertLinegoHorzLine,但没有任何效果。

下面是一些示例代码:

LGrid := TStringGrid(Sender); 
LGrid.Canvas.Brush.Color := clYellow + 1000 * (1 + ARow); 
if ACol = LGrid.ColCount - 1 then 
    Rect.Right := LGrid.ClientRect.Right; // Doesn't have any effect 
LGrid.Canvas.FillRect(Rect); 

什么是要达到什么上面的代码预期的最简单的方法?我希望能够在不写一个插页类的情况下在那里绘画,覆盖Paint方法,并且使用这个事件实现大部分已经可用的内容。

回答

1

在绘制完单元格后,VCL填充未被单元格占据的空白区域。这就是为什么你的绘画过度绘制。可以使用事件处理程序立即防止您绘制的内容被删除,无需重写Paint或派生新的控件。由于VCL使用相同的设备上下文绘制单元格和空白区域,因此可以剪出刚刚从设备上下文中绘制的扩展矩形,操作系统将忽略VCL后来为该区域绘制的调用。

LGrid := TStringGrid(Sender); 
LGrid.Canvas.Brush.Color := clYellow + 1000 * (1 + ARow); 
if ACol = LGrid.ColCount - 1 then 
    Rect.Right := LGrid.ClientRect.Right; 
LGrid.Canvas.FillRect(Rect); 
ExcludeClipRect(LGrid.Canvas.Handle, Rect.Left, Rect.Top, Rect.Right, Rect.Bottom); // <-- 
+0

虽然'ExcludeClipRect'确实会阻止该区域被擦除 - 我学到了一些东西:) - 不幸的是整体结果并不如我所希望的那样。现在,我可以成功绘制的区域在更改选区或调整大小时不会重新绘制。也许在更多情况下。不过,不确定是否解决了这个问题的范围。 –

+0

@Thijs - OnDrawCell在调整大小(放大空白区域)时可能不会被调用。在这种情况下,我认为不可能在OnDrawCell中包含干预。我无法猜测为什么选择不起作用,但... –

+0

要强制重绘,可以使用OnResize,OnSelectCell和OnTopLeftChanged事件来手动对整个网格进行Invalidate() InvalidateRect()'所需的部分。 –

相关问题