【问题标题】:How to change cell color in a TCalendar Component in Delphi?如何在 Delphi 的 TCalendar 组件中更改单元格颜色?
【发布时间】:2015-11-10 14:14:52
【问题描述】:

我需要在适用于 Android 和 iOS 的应用程序的 TCalendar 组件中更改某些单元格的颜色。我正在使用 Delphi Seattle 10。有什么办法吗?

【问题讨论】:

    标签: android ios delphi calendar delphi-10-seattle


    【解决方案1】:

    这在 Delphi XE5 下工作。不幸的是,我没有 Delphi 10 来检查代码。

    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 <> [] then
      begin
        LB := TListBox(TStyleObject(Children.Items[0]).Children.Items
          [TStyleObject(Children.Items[0]).Children.Count - 1]);
        for i := 0 to LB.Count - 1 do
          if (Assigned(LB.ItemByIndex(i))) and
            (StrToInt(LB.ItemByIndex(i).Text) in FSelectedDays) then
          begin
            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)) do
            begin
              Parent := LB.ItemByIndex(i);
              Align := TAlignLayout.alClient;
              Fill.Color := TAlphaColorRec.Red;
              Opacity := 0.5;
            end;
          end;
      end;
    end;
    

    然后创建一个 TMyCalendar 类的实例:

      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 and check the month
    end;
    

    附加

    还有另一种访问私有变量 FDays 的方法,该变量代表一个月中的日期列表。你声明了一个 class helper 在属性 Days 中公开它:

      TMyCalendarHelper = class helper for TCalendar
        function GetDays: TListBox;
        procedure SetDays(const Value: TListBox);
        property Days: TListBox read GetDays write SetDays;
      end;
    
    ...
    
    { TMyCalendarHelper }
    
    function TMyCalendarHelper.GetDays: TListBox;
    begin
      result := Self.FDays;
    end;
    
    procedure TMyCalendarHelper.SetDays(const Value: TListBox);
    begin
      Self.FDays := Value;
    end;
    

    然后在 cals 后代中,您可以使用 Days 属性控制此 ListBox 及其项。

    procedure TMyCalendar.ApplyStyle;
    var
      i: 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)
    

    附加 2 有可能更正日期的绘制方式。

      TMyCalendar = class(TCalendar)
      private
        FSelectedDays: set of byte;
        procedure PaintChildren; override;
      end;
    procedure TMyCalendar.PaintChildren;
    var
      i: word;
      TMPC: TAlphaColor;
      R: TRectF;
    begin
      inherited;
      if FSelectedDays <> [] then
      begin
        for i := 0 to Days.Count - 1 do
          if (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; 
    

    【讨论】:

    • @elcharlie 我附加了另一种访问 FDays 私有变量的方法。
    • 不幸的是,它在 Delphi 西雅图我不起作用,向我显示日历几天不显示单元格:(
    • @elcharlie 请具体说明,究竟是什么不起作用。你有能力控制Days.ItemByIndex(i)吗?是Assigned(Days)=true
    • 抱歉,在 delphi 10 中,TCalendar 对象中没有名为 FDays 的属性
    • 最后,我成功了。最后我按照你一开始说的做了,辅助类我一直做不到。非常感谢您所做的一切。
    猜你喜欢
    • 2011-10-05
    • 2018-07-20
    • 1970-01-01
    • 2014-08-24
    • 2011-06-23
    • 1970-01-01
    • 2013-10-30
    • 1970-01-01
    相关资源
    最近更新 更多