Delphi 11社区版TInplaceEdit的Color属性失效问题求助
Delphi 11 中 TInplaceEdit 背景色设置失效的问题
我这段修改TInplaceEdit背景色的代码在Delphi 2010中可以正常运行,但在Delphi 11社区版里背景色设置失效,不过CharCase属性还能正常工作。查了很多示例都没解决,请问问题出在哪?
原代码
type TMyInplaceEdit = class(TInplaceEdit) public property Color; // 重新声明为公共属性 constructor Create(AOwner: TComponent); override; end; TTestGrid = class(TStringGrid) public property InplaceEditor; // 重新声明为公共属性 function CreateEditor: TInplaceEdit; override; end; TForm1 = class(TForm) procedure FormShow(Sender: TObject); private { Private declarations } public TestGrid: TTestGrid; end; var Form1: TForm1; implementation {$R *.dfm} constructor TMyInplaceEdit.Create(AOwner: TComponent); begin inherited; Color := clMoneyGreen; CharCase := ecUpperCase; end; function TTestGrid.CreateEditor: TInplaceEdit; begin inherited;// 去掉这行结果也一样 Result := TMyInplaceEdit.Create(self); end; procedure TForm1.FormShow(Sender: TObject); begin TestGrid := TTestGrid.Create(Self); TestGrid.Parent := Self; TestGrid.Show; TestGrid.Options := [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine, goEditing, goTabs]; end;
问题原因
- 编辑器逻辑变更:Delphi 10.4+(包括11)的
TStringGrid内部对CreateEditor的返回值处理逻辑改变了——即便你返回自定义编辑器实例,网格后续仍会通过其他逻辑重置编辑器,导致背景色设置被覆盖。 - 主题样式覆盖:新版本VCL的主题系统会优先使用主题样式渲染控件,
TInplaceEdit的Color属性会被主题样式覆盖,除非明确禁用主题对该控件的影响。 CreateEditor调用错误:调用inherited会先创建默认编辑器,之后你创建的自定义编辑器并没有被网格正确关联,导致设置失效。
修正方案
type TMyInplaceEdit = class(TInplaceEdit) public property Color; constructor Create(AOwner: TComponent); override; end; TTestGrid = class(TStringGrid) private procedure SyncEditorColor; protected function CreateEditor: TInplaceEdit; override; procedure DrawCell(ACol, ARow: Integer; ARect: TRect; AState: TGridDrawState); override; procedure EditShow; override; public property InplaceEditor; end; TForm1 = class(TForm) procedure FormShow(Sender: TObject); private { Private declarations } public TestGrid: TTestGrid; end; var Form1: TForm1; implementation {$R *.dfm} constructor TMyInplaceEdit.Create(AOwner: TComponent); begin inherited; Color := clMoneyGreen; CharCase := ecUpperCase; // 禁用主题对客户端区域的渲染,确保自定义颜色生效 StyleElements := StyleElements - [seClient]; end; function TTestGrid.CreateEditor: TInplaceEdit; begin // 不调用inherited,直接创建自定义编辑器 Result := TMyInplaceEdit.Create(Self); end; procedure TTestGrid.DrawCell(ACol, ARow: Integer; ARect: TRect; AState: TGridDrawState); begin inherited; // 编辑状态下提前绘制单元格背景色,避免编辑器显示前的闪烁 if (ACol = Col) and (ARow = Row) and (goEditing in Options) then begin Canvas.Brush.Color := clMoneyGreen; Canvas.FillRect(ARect); Canvas.TextOut(ARect.Left + 2, ARect.Top + 2, Cells[ACol, ARow]); end; end; procedure TTestGrid.SyncEditorColor; begin // 确保编辑器显示时颜色正确 if InplaceEditor is TMyInplaceEdit then TMyInplaceEdit(InplaceEditor).Color := clMoneyGreen; end; procedure TTestGrid.EditShow; begin inherited; SyncEditorColor; end; procedure TForm1.FormShow(Sender: TObject); begin TestGrid := TTestGrid.Create(Self); TestGrid.Parent := Self; TestGrid.Align := alClient; TestGrid.Options := [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine, goEditing, goTabs]; // 添加测试单元格内容 TestGrid.Cells[0, 1] := 'edit me'; end;
关键修改点
- 移除
CreateEditor中的inherited调用,确保网格使用自定义编辑器实例; - 在
TMyInplaceEdit中禁用主题对客户端区域的影响,避免颜色被覆盖; - 重写
DrawCell方法,提前绘制编辑单元格的背景色,解决闪烁问题; - 重写
EditShow方法,在编辑器显示时同步颜色设置,确保万无一失。
内容的提问来源于stack exchange,提问作者Rudi
相关产品推荐
相关产品推荐

