如何取消FMX ListBox选中项默认0.7的背景不透明度限制?
解决FMX ListBox选中项默认0.7不透明度的问题
核心问题原因
FMX框架中TCustomListBox默认定义了TCustomListBox_UnfocusedSelectionOpacity和TCustomListBox_ExtendedSelectionOpacity两个常量,值均为0.7,导致无论自定义选中颜色为何,都会叠加该透明度,无法显示纯色效果。
可行解决方案:重写ListBox的选中绘制逻辑
通过继承TListBox(或TCustomListBox),重写DrawSelection方法,直接指定选中背景的不透明度为1.0(完全不透明),避开框架默认的常量限制。
Delphi代码示例
type TMyListBox = class(TListBox) protected procedure DrawSelection(const ARect: TRectF; const AState: TCustomListBox.TItemState); override; end; procedure TMyListBox.DrawSelection(const ARect: TRectF; const AState: TCustomListBox.TItemState); var LOpacity: Single; begin case AState of TCustomListBox.TItemState.isSelected, TCustomListBox.TItemState.isSelectedUnfocused, TCustomListBox.TItemState.isSelectedExtended: LOpacity := 1.0; // 设置为完全不透明,按需调整 else LOpacity := 0; end; Canvas.Fill.Color := SelectedColor; Canvas.Fill.Kind := TBrushKind.Solid; Canvas.Fill.Opacity := LOpacity; Canvas.FillRect(ARect, 0, 0, [], 1); end;
C++Builder代码示例
class TMyListBox : public TListBox { protected: virtual void __fastcall DrawSelection(const TRectF &ARect, const TCustomListBox::TItemState AState); }; void __fastcall TMyListBox::DrawSelection(const TRectF &ARect, const TCustomListBox::TItemState AState) { float LOpacity = 0.0f; switch(AState) { case TCustomListBox::TItemState::isSelected: case TCustomListBox::TItemState::isSelectedUnfocused: case TCustomListBox::TItemState::isSelectedExtended: LOpacity = 1.0f; // 完全不透明,可根据需求修改 break; default: LOpacity = 0.0f; break; } Canvas->Fill->Color = SelectedColor; Canvas->Fill->Kind = TBrushKind::Solid; Canvas->Fill->Opacity = LOpacity; Canvas->FillRect(ARect, 0, 0, nullptr, 1); }
适配ComboBox的场景
若需解决ComboBox下拉列表的同样问题,可继承TComboBox,重写CreateListBox方法,替换内部列表为自定义的TMyListBox:
Delphi代码示例
type TMyComboBox = class(TComboBox) protected function CreateListBox: TCustomListBox; override; end; function TMyComboBox.CreateListBox: TCustomListBox; begin Result := TMyListBox.Create(Self); Result.Parent := Self; end;
C++Builder代码示例
class TMyComboBox : public TComboBox { protected: virtual TCustomListBox* __fastcall CreateListBox(void); }; TCustomListBox* __fastcall TMyComboBox::CreateListBox(void) { TMyListBox* ListBox = new TMyListBox(this); ListBox->Parent = this; return ListBox; }
方案优势
- 完全保留
Selected属性的正常功能,不会破坏原有选中状态逻辑 - 直接从绘制层解决问题,无需通过取消选中状态等hack方式实现效果
- 可灵活调整不透明度值,满足不同场景需求
内容的提问来源于stack exchange,提问作者Bruce
相关产品推荐
相关产品推荐

