FMX的控件的外观以Style为主,但是也有不方便的地方,比如要任意改变TPanel的颜色,只能写代码,摸索了几天,初步实现了
unit FMX.JKPanelEx; interface uses System.SysUtils, System.Classes, System.Types, System.UITypes, FMX.Types, FMX.Controls, FMX.Objects, FMX.Graphics, FMX.Controls.Presentation, FMX.StdCtrls; type TAppearanceUpdateKind = (None, Fill, Stroke, CornerSize); TJKPanelEx = class(TPanel) private FAppearance: TRectangle; FFill: TBrush; FStroke: TStrokeBrush; FCornerSize: Single; FAppearanceUpdateKind: TAppearanceUpdateKind; procedure SetFill(const Value: TBrush); procedure SetStroke(const Value: TStrokeBrush); procedure SetCornerSize(const Value: Single); protected procedure ApplyStyle; override; procedure FreeStyle; override; procedure FillChanged(Sender: TObject); virtual; procedure StrokeChanged(Sender: TObject); virtual; procedure UpdateAppearanceFill; procedure UpdateAppearanceStroke; procedure UpdateAppearanceCornerSize; procedure UpdateAppearance; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; property Appearance: TRectangle read FAppearance write FAppearance; published property Fill: TBrush read FFill write SetFill; property Stroke: TStrokeBrush read FStroke write SetStroke; property CornerSize: Single read FCornerSize write SetCornerSize; end; procedure Register; implementation procedure Register; begin RegisterComponents('JKFMXControl', [TJKPanelEx]); end; { TJKPanelEx } procedure TJKPanelEx.ApplyStyle; begin inherited; if not Assigned(FAppearance) then begin if not FindStyleResource<TRectangle>('Background', FAppearance) and (ResourceControl is TRectangle) then FAppearance := TRectangle(ResourceControl); UpdateAppearanceCornerSize; UpdateAppearanceFill; UpdateAppearanceStroke; end else begin UpdateAppearance; end; end; constructor TJKPanelEx.Create(AOwner: TComponent); begin inherited; FAppearance := nil; FAppearanceUpdateKind := TAppearanceUpdateKind.None; FFill := TBrush.Create(TBrushKind.Solid, TAlphaColor($FFE0E0E0)); FStroke := TStrokeBrush.Create(TBrushKind.Solid, TAlphaColors.Black); FFill.OnChanged := FillChanged; FStroke.OnChanged := StrokeChanged; end; destructor TJKPanelEx.Destroy; begin FreeAndNil(FFill); FreeAndNil(FStroke); inherited; end; procedure TJKPanelEx.FillChanged(Sender: TObject); begin FAppearanceUpdateKind := TAppearanceUpdateKind.Fill; ApplyStyle; end; procedure TJKPanelEx.FreeStyle; begin inherited; FAppearance := nil; end; procedure TJKPanelEx.SetCornerSize(const Value: Single); begin if FCornerSize <> Value then begin FAppearanceUpdateKind := TAppearanceUpdateKind.CornerSize; FCornerSize := Value; UpdateAppearanceCornerSize; end; end; procedure TJKPanelEx.SetFill(const Value: TBrush); begin FFill.Assign(Value); end; procedure TJKPanelEx.SetStroke(const Value: TStrokeBrush); begin FStroke.Assign(Value); end; procedure TJKPanelEx.StrokeChanged(Sender: TObject); begin FAppearanceUpdateKind := TAppearanceUpdateKind.Stroke; ApplyStyle; end; procedure TJKPanelEx.UpdateAppearance; begin case FAppearanceUpdateKind of TAppearanceUpdateKind.None: ; TAppearanceUpdateKind.Fill: UpdateAppearanceFill; TAppearanceUpdateKind.Stroke: UpdateAppearanceStroke; TAppearanceUpdateKind.CornerSize: UpdateAppearanceCornerSize; end; end; procedure TJKPanelEx.UpdateAppearanceFill; begin if FAppearance <> nil then begin FAppearance.Fill.Assign(FFill); end; end; procedure TJKPanelEx.UpdateAppearanceStroke; begin if FAppearance <> nil then begin FAppearance.Stroke.Assign(FStroke); end; end; procedure TJKPanelEx.UpdateAppearanceCornerSize; begin if FAppearance <> nil then begin FAppearance.XRadius := FCornerSize; FAppearance.YRadius := FCornerSize; end; end; end.