Skip to content Skip to sidebar Skip to footer

How To Change Cell Color In A Tcalendar Component In Delphi?

I need to change the colour of some cell, in a TCalendar component on an app that will work on Android and iOS. I'm Using Delphi Seattle 10. Is there any way to do it?

Solution 1:

This works under Delphi XE5. Unfortunateley, I do not have Delphi 10 to check the code.

type
  TMyCalendar = class(TCalendar)
  private
    FSelectedDays: set of byte;
    procedure ApplyStyle; override;
  end;

...

{ TMyCalendar }

procedure TMyCalendar.ApplyStyle;
var
  i: word;
  LB: TListBox;
begin
  inherited;
  if FSelectedDays <> [] thenbegin
    LB := TListBox(TStyleObject(Children.Items[0]).Children.Items
      [TStyleObject(Children.Items[0]).Children.Count - 1]);
    for i := 0 to LB.Count - 1doif (Assigned(LB.ItemByIndex(i))) and
        (StrToInt(LB.ItemByIndex(i).Text) in FSelectedDays) thenbegin
        LB.ItemByIndex(i).StyledSettings := LB.ItemByIndex(i).StyledSettings -
          [TStyledSetting.ssStyle];
        LB.ItemByIndex(i).Font.Style := LB.ItemByIndex(i).Font.Style +
          [TFontStyle.fsBold];
        With TRectangle.Create(LB.ItemByIndex(i)) dobegin
          Parent := LB.ItemByIndex(i);
          Align := TAlignLayout.alClient;
          Fill.Color := TAlphaColorRec.Red;
          Opacity := 0.5;
        end;
      end;
  end;
end;

And then create an instance of TMyCalendar class:

  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    MyCalendar: TMyCalendar;
  end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  MyCalendar := TMyCalendar.Create(Self);
  MyCalendar.Parent := Self;
  MyCalendar.Position.X :=1;
  MyCalendar.Position.Y :=1;
  MyCalendar.FSelectedDays := [9, 11]; //<-set other days here andcheck the monthend;

APPENDED

There is another way to get access to the private variable FDays that reperesents the list of days of the month. You declare a class helper exposing it in the property Days:

  TMyCalendarHelper = class helper for TCalendar
    functionGetDays: TListBox;
    procedureSetDays(const Value: TListBox);
    property Days: TListBox read GetDays write SetDays;
  end;

...

{ TMyCalendarHelper }

functionTMyCalendarHelper.GetDays: TListBox;
beginresult := Self.FDays;
end;

procedureTMyCalendarHelper.SetDays(const Value: TListBox);
begin
  Self.FDays := Value;
end;

And then in the calss descendant you get control over this ListBox and its items using Days property.

procedure TMyCalendar.ApplyStyle;
vari: word;
//  LB: TListBox;//<-you do not need it any more
begin
  inherited;
  if FSelectedDays <> [] then
  begin
//    LB := TListBox(TStyleObject(Children.Items[0]).Children.Items//<-you do not need it
//      [TStyleObject(Children.Items[0]).Children.Count - 1]);//<-you do not need it
    for i := 0 to Days.Count - 1 do
      if (Assigned(Days.ItemByIndex(i))) and
        (StrToInt(Days.ItemByIndex(i).Text) in FSelectedDays) then
      begin
        Days.ItemByIndex(i).StyledSettings := Days.ItemByIndex(i).StyledSettings -
          [TStyledSetting.ssStyle];
        Days.ItemByIndex(i).Font.Style := Days.ItemByIndex(i).Font.Style +
          [TFontStyle.fsBold];
        //Do other things you want with Days.ItemByIndex(i)

APPENDED 2 There is a possibility to correct the way the days are drawn.

  TMyCalendar = class(TCalendar)
  private
    FSelectedDays: setofbyte;
    procedure PaintChildren; override;
  end;
procedure TMyCalendar.PaintChildren;
var
  i: word;
  TMPC: TAlphaColor;
  R: TRectF;
begin
  inherited;
  if FSelectedDays <> [] then
  begin
    for i := 0to Days.Count - 1doif (Assigned(Days.ItemByIndex(i))) and
        (StrToInt(Days.ItemByIndex(i).Text) in FSelectedDays) then
      begin
        TMPC := Days.ItemByIndex(i).Canvas.Fill.Color;
        R := Days.ItemByIndex(i).AbsoluteRect;
        R.Inflate(Position.X, Position.Y, -Position.X, -Position.Y);
        Days.ItemByIndex(i).Canvas.BeginScene;
        Days.ItemByIndex(i).Canvas.Fill.Color := TAlphaColorRec.Red;
        Days.ItemByIndex(i).Canvas.FillRect(R, 0, 0, [], 0.5);
        Days.ItemByIndex(i).Canvas.EndScene;
        Days.ItemByIndex(i).Canvas.Fill.Color := TMPC;
      end;
  end;
end; 

Post a Comment for "How To Change Cell Color In A Tcalendar Component In Delphi?"