是的,如果您只对控件的源代码进行少量修改,这很容易。具体来说,我们需要在其上添加少量代码DrawCell
method.
最初,这是
procedure TCalendar.DrawCell(ACol, ARow: Longint; ARect: TRect; AState: TGridDrawState);
var
TheText: string;
begin
TheText := CellText[ACol, ARow];
with ARect, Canvas do
TextRect(ARect, Left + (Right - Left - TextWidth(TheText)) div 2,
Top + (Bottom - Top - TextHeight(TheText)) div 2, TheText);
end;
将其更改为:
procedure TCalendar.DrawCell(ACol, ARow: Longint; ARect: TRect; AState: TGridDrawState);
var
TheText: string;
i: Integer;
Day: Integer;
begin
TheText := CellText[ACol, ARow];
with ARect, Canvas do
begin
Font.Style := [];
for i := Low(HighlightDates) to High(HighlightDates) do
if TryStrToInt(TheText, Day) then
if SameDate(HighlightDates[i], EncodeDate(Year, Month, Day)) then
begin
Font.Style := [fsBold];
Break;
end;
TextRect(ARect, Left + (Right - Left - TextWidth(TheText)) div 2,
Top + (Bottom - Top - TextHeight(TheText)) div 2, TheText);
end;
end;
快速尝试此操作的最简单方法是使用插入器类:
type
TCalendar = class(Vcl.Samples.Calendar.TCalendar)
procedure DrawCell(ACol, ARow: Longint; ARect: TRect; AState: TGridDrawState); override;
end;
TForm1 = class(TForm)
...
现在您只需提供一组日期即可突出显示:
var
HighlightDates: TArray<TDate>;
procedure TForm1.FormCreate(Sender: TObject);
begin
SetLength(HighlightDates, 3);
HighlightDates[0] := EncodeDate(2020, 07, 10);
HighlightDates[1] := EncodeDate(2020, 07, 20);
HighlightDates[2] := EncodeDate(2020, 08, 10);
end;
或者,在新的 Delphi 版本(XE7 及更高版本)中,
procedure TForm1.FormCreate(Sender: TObject);
begin
HighlightDates :=
[
EncodeDate(2020, 07, 10),
EncodeDate(2020, 07, 20),
EncodeDate(2020, 08, 10)
];
end;
不要忘记添加DateUtils
to the uses
clause.
(我为瑞典的节日名称表示歉意。)
不用说,您可以按照您喜欢的任何方式绘制突出显示的单元格;使字体加粗只是一种可能性。如果您想通过在右上角画一个苯环来突出显示一个单元格,也可以。
您将需要使用新代码创建一个新控件。在此,日期数组将是其中的一个成员。它可能具有与 setter 关联的属性,该属性也会使控件无效。此外,您还可以添加公共HighlightDate(const ADate: TDate)
and StopHighlightDate(const ADate: TDate)
在此数组中添加和删除日期(并使控件无效)的过程。
Update
根据要求(请参阅评论),以下是如何更改突出显示单元格的背景颜色:
{ TCalendar }
procedure TCalendar.DrawCell(ACol, ARow: Longint; ARect: TRect;
AState: TGridDrawState);
var
TheText: string;
i: Integer;
Day: Integer;
OldColor: TColor;
begin
TheText := CellText[ACol, ARow];
with ARect, Canvas do
begin
OldColor := Brush.Color;
for i := Low(HighlightDates) to High(HighlightDates) do
if TryStrToInt(TheText, Day) then
if SameDate(HighlightDates[i], EncodeDate(Year, Month, Day)) then
begin
Brush.Color := clSkyBlue;
FillRect(ARect);
Break;
end;
TextRect(ARect, Left + (Right - Left - TextWidth(TheText)) div 2,
Top + (Bottom - Top - TextHeight(TheText)) div 2, TheText);
Brush.Color := OldColor;
end;
end;