You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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;

问题原因

  1. 编辑器逻辑变更:Delphi 10.4+(包括11)的TStringGrid内部对CreateEditor的返回值处理逻辑改变了——即便你返回自定义编辑器实例,网格后续仍会通过其他逻辑重置编辑器,导致背景色设置被覆盖。
  2. 主题样式覆盖:新版本VCL的主题系统会优先使用主题样式渲染控件,TInplaceEdit的Color属性会被主题样式覆盖,除非明确禁用主题对该控件的影响。
  3. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 07:50:58