如何自定义TcxPageControl中pcoGoDialog弹出菜单的选中颜色?
解决方案
要修改TcxPageControl的GoDialog弹出菜单选中颜色,需要拦截该内部弹出菜单的绘制事件,自定义选中项的背景和文字颜色。以下是具体实现步骤:
- 子类化TcxPageControl,重写菜单创建方法
重写CreateGoDialogMenu方法,获取内部生成的弹出菜单实例,并绑定自定义绘制事件。 - 实现自定义菜单绘制事件
在绘制事件中判断菜单项的选中状态,替换默认的蓝色高亮为自定义颜色。
修改后的完整代码
unit Unit2; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, dxBarBuiltInMenu, cxGraphics, cxControls, cxLookAndFeels, cxLookAndFeelPainters, dxSkinsCore, dxSkinBasic, cxPC, cxPCPainters, cxPCPaintersFactory, dxBarMenus, dxBar; const MyStyleId = 100; type // 子类化TcxPageControl以拦截GoDialog菜单创建 TMycxPageControl = class(TcxPageControl) protected function CreateGoDialogMenu: TdxBarPopupMenu; override; end; TForm2 = class(TForm) cxPageControl1: TMycxPageControl; // 注意这里类改为TMycxPageControl cxTabSheet1: TcxTabSheet; cxTabSheet2: TcxTabSheet; cxTabSheet3: TcxTabSheet; cxTabSheet4: TcxTabSheet; cxTabSheet5: TcxTabSheet; cxTabSheet6: TcxTabSheet; cxTabSheet7: TcxTabSheet; procedure FormCreate(Sender: TObject); procedure cxPageControl1DrawTabEx(AControl: TcxCustomTabControl; ATab: TcxTab; Font: TFont); private procedure MyPopupMenuDrawItem(Sender: TObject; ACanvas: TCanvas; AItem: TdxBarItem; AItemRect: TRect; AState: TdxBarItemState); public end; TMyPCPainter = class(TcxPCUltraFlatPainter) private class function GetStyleID: TcxPCStyleID; static; protected function GetTabsRowColor: TColor; override; function GetTabCorrection(ATabVisibleIndex: Integer): TRect; override; function GetButtonColor(AButtonState: TcxPCNavigatorButtonState): TColor; override; public end; var Form2: TForm2; implementation {$R *.dfm} { TMycxPageControl } function TMycxPageControl.CreateGoDialogMenu: TdxBarPopupMenu; begin Result := inherited CreateGoDialogMenu; // 绑定自定义绘制事件 Result.OnDrawItem := Form2.MyPopupMenuDrawItem; end; { TMyPCPainter } function TMyPCPainter.GetButtonColor(AButtonState: TcxPCNavigatorButtonState): TColor; begin Result := clGray; end; class function TMyPCPainter.GetStyleID: TcxPCStyleID; begin Result := MyStyleId; end; function TMyPCPainter.GetTabCorrection(ATabVisibleIndex: Integer): TRect; begin // 增加标签间距 Result := Rect(5, -1, 0, 2); end; function TMyPCPainter.GetTabsRowColor: TColor; begin Result := clGray; end; { TForm2 } procedure TForm2.cxPageControl1DrawTabEx(AControl: TcxCustomTabControl; ATab: TcxTab; Font: TFont); begin if ATab.IsMainTab then begin ATab.Color := clWhite; Font.Color := clBlack; end else begin ATab.Color := clBlack; Font.Color := clWhite; end; end; procedure TForm2.FormCreate(Sender: TObject); begin cxPageControl1.Style := MyStyleId; cxPageControl1.OnDrawTabEx := cxPageControl1DrawTabEx; end; procedure TForm2.MyPopupMenuDrawItem(Sender: TObject; ACanvas: TCanvas; AItem: TdxBarItem; AItemRect: TRect; AState: TdxBarItemState); var LTextRect: TRect; begin // 绘制默认背景 ACanvas.Brush.Color := clWindow; ACanvas.FillRect(AItemRect); // 判断是否为选中状态(鼠标悬停或选中) if bisSelected in AState then begin // 设置自定义选中背景色(这里用clMaroon,可替换为你需要的颜色) ACanvas.Brush.Color := clMaroon; ACanvas.FillRect(AItemRect); // 设置选中时的文字颜色 ACanvas.Font.Color := clWhite; end else begin // 默认文字颜色 ACanvas.Font.Color := clWindowText; end; // 绘制菜单项文本 LTextRect := AItemRect; InflateRect(LTextRect, -2, 0); // 调整文本边距 DrawText(ACanvas.Handle, PChar(AItem.Caption), Length(AItem.Caption), LTextRect, DT_LEFT or DT_VCENTER or DT_SINGLELINE); end; initialization RegisterPCPainterClass(TMyPCPainter); finalization UnregisterPCPainterClass(TMyPCPainter); end.
注意事项
- 修改DFM文件:如果是在设计时添加的TcxPageControl,需要打开DFM文件(右键窗体 -> View as Text),将
object cxPageControl1: TcxPageControl改为object cxPageControl1: TMycxPageControl,否则运行时会报错。 - 自定义颜色:代码中
clMaroon是示例选中背景色,你可以替换为任意TColor值(比如clGreen、$00FFCC99等)。 - 图标处理:如果菜单项包含图标,需要在
MyPopupMenuDrawItem中添加图标绘制逻辑,可参考DevExpress的默认绘制代码实现。
内容的提问来源于stack exchange,提问作者DelphiLearner
相关产品推荐
相关产品推荐

