如何保留TControlCanvas全部属性并恢复?TDBGridEh自定义绘制问题
解决TDBGridEh自定义绘制单元格时的属性冲突与画布赋值异常问题
我来帮你梳理这个问题的解决思路,你遇到的两个核心问题其实是关联的,咱们一步步拆解:
为什么绘制效果混乱?
TDBGridEh的OnDrawCell事件执行完你的自定义代码后,控件会自动执行默认绘制逻辑,这时候它会使用你修改后的Pen、Brush等属性,导致和你自定义的效果冲突、画面混乱。所以核心需求是:在自定义绘制时临时修改画布属性,绘制完成后立刻恢复成原始状态,让控件后续的默认绘制不受影响。
为什么会触发“Cannot assign a TControlCanvas to a TControlCanvas”异常?
TControlCanvas是和具体控件绑定的画布类,它的Assign方法不支持直接把一个TControlCanvas赋值给另一个——因为两者关联的Control对象是不同的(你新建的TControlCanvas没有绑定任何控件,而网格的Canvas绑定的是DBGridEh本身),直接赋值会触发类型检查异常。这个思路从根源上就不对,咱们不需要新建画布,只需要保存当前画布的属性即可。
正确的实现方案:保存+恢复画布属性
直接用TPen、TBrush、TFont的实例来临时保存画布的原始属性,自定义绘制完成后再把这些属性赋值回去。下面是具体的代码示例:
procedure TYourForm.DBGridEh1DrawCell(Sender: TObject; const Rect: TRect; Field: TField; State: TGridDrawState); var SavedPen: TPen; SavedBrush: TBrush; SavedFont: TFont; begin // 初始化临时对象,保存画布原始属性 SavedPen := TPen.Create; SavedBrush := TBrush.Create; SavedFont := TFont.Create; try SavedPen.Assign(DBGridEh1.Canvas.Pen); SavedBrush.Assign(DBGridEh1.Canvas.Brush); SavedFont.Assign(DBGridEh1.Canvas.Font); // -------------------------- // 这里写你的自定义绘制逻辑 // 示例:设置单元格背景为浅蓝色,字体加粗深蓝色 DBGridEh1.Canvas.Brush.Color := clSkyBlue; DBGridEh1.Canvas.Font.Color := clNavy; DBGridEh1.Canvas.Font.Style := [fsBold]; // 绘制单元格背景 DBGridEh1.Canvas.FillRect(Rect); // 绘制单元格文本(如果有字段的话) if Assigned(Field) then DBGridEh1.Canvas.TextOut(Rect.Left + 2, Rect.Top + 2, Field.AsString); // -------------------------- finally // 恢复画布的原始属性,确保控件后续默认绘制正常 DBGridEh1.Canvas.Pen.Assign(SavedPen); DBGridEh1.Canvas.Brush.Assign(SavedBrush); DBGridEh1.Canvas.Font.Assign(SavedFont); // 释放临时对象 SavedPen.Free; SavedBrush.Free; SavedFont.Free; end; end;
额外提示:跳过默认绘制(可选)
如果你想完全接管单元格的绘制,不需要控件执行后续默认逻辑,可以在事件中设置DefaultDraw := False;(注意:部分版本的TDBGridEh的OnDrawCell事件参数包含这个变量,需要确认你的控件版本)。这种情况下你不需要恢复属性,但要自己处理所有绘制细节,比如选中状态、网格线、焦点框等。
内容的提问来源于stack exchange,提问作者saastn
相关产品推荐
相关产品推荐

