You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Delphi 12.3中TCalendar组件如何同时高亮非连续单元格?

在Delphi 12.3中实现TCalendar多非连续日期高亮

可以实现,核心思路是利用TCalendar的OnDrawCell事件进行自定义绘制,同时维护一个存储需要高亮日期的集合。以下是具体实现步骤:

1. 准备日期存储集合

首先定义一个类级别的集合来保存需要高亮的日期,确保只存储日期部分(忽略时间):

uses System.Generics.Collections;

type
  TForm1 = class(TForm)
    Calendar1: TCalendar;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Calendar1DrawCell(Sender: TObject; const ADate: TDateTime;
      const ARect: TRect; AState: TCalendarCellState);
    procedure Calendar1Click(Sender: TObject);
  private
    FHighlightedDates: TList<TDateTime>;
    function IsDateHighlighted(const ADate: TDateTime): Boolean;
  public
  end;

在窗体创建和销毁时初始化/释放集合:

procedure TForm1.FormCreate(Sender: TObject);
begin
  FHighlightedDates := TList<TDateTime>.Create;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  FHighlightedDates.Free;
end;

2. 日期高亮判断方法

写一个辅助函数,判断当前单元格的日期是否在高亮集合中(仅比较日期部分):

function TForm1.IsDateHighlighted(const ADate: TDateTime): Boolean;
var
  I: Integer;
begin
  Result := False;
  for I := 0 to FHighlightedDates.Count - 1 do
  begin
    if Trunc(ADate) = Trunc(FHighlightedDates[I]) then
    begin
      Result := True;
      Break;
    end;
  end;
end;

3. 自定义单元格绘制逻辑

在OnDrawCell事件中,对需要高亮的日期单独绘制背景和文本,其他日期使用默认绘制:

procedure TForm1.Calendar1DrawCell(Sender: TObject; const ADate: TDateTime;
  const ARect: TRect; AState: TCalendarCellState);
var
  DateText: string;
begin
  if IsDateHighlighted(ADate) then
  begin
    // 设置高亮背景色
    Calendar1.Canvas.Brush.Color := $00FFE0C0; // 浅橙色,可自定义
    Calendar1.Canvas.FillRect(ARect);
    // 设置高亮文本颜色
    Calendar1.Canvas.Font.Color := clMaroon;
    // 居中绘制日期文本
    DateText := DateToStr(ADate);
    Calendar1.Canvas.TextOut(
      ARect.Left + (ARect.Width - Calendar1.Canvas.TextWidth(DateText)) div 2,
      ARect.Top + (ARect.Height - Calendar1.Canvas.TextHeight(DateText)) div 2,
      DateText
    );
  end
  else
  begin
    // 非高亮日期使用默认绘制逻辑
    Calendar1.DefaultDrawCell(ADate, ARect, AState);
  end;
end;

4. 添加用户交互(点击标记/取消高亮)

处理OnClick事件,让用户点击日期时切换其高亮状态:

procedure TForm1.Calendar1Click(Sender: TObject);
var
  TargetDate: TDateTime;
  I: Integer;
begin
  TargetDate := Trunc(Calendar1.Date);
  // 检查日期是否已高亮,是则移除
  for I := 0 to FHighlightedDates.Count - 1 do
  begin
    if Trunc(FHighlightedDates[I]) = TargetDate then
    begin
      FHighlightedDates.Delete(I);
      Calendar1.Invalidate; // 刷新日历界面
      Exit;
    end;
  end;
  // 未高亮则添加到集合
  FHighlightedDates.Add(TargetDate);
  Calendar1.Invalidate;
end;

额外提示

  • 可根据需求修改高亮的背景色、文本色,甚至添加边框等视觉效果;
  • 如果需要持久化高亮日期,可将集合中的日期保存到配置文件或数据库,启动时重新加载;
  • 始终使用Trunc处理日期,避免因TDateTime的时间部分导致匹配错误。

内容的提问来源于stack exchange,提问作者Moore

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.11 10:03:20