4

我正在使用 TDateTimePicker 来允许用户选择一天(手动或通过单击按钮前进或后退一天)。然后,用户将看到该特定日期的日志条目。

该控件效果很好,但我想将用户限制在 [OLDEST-DAY-IN-LOG] 和 [TODAY] 之间,因为这些是有数据的日期限制。

我已经在 TDateTimePicker 上设置了 MinDate 和 MaxDate 并且效果很好。选择允许范围之外的日期不会执行任何操作。

我的问题是是否可以将无效日期绘制为灰色。在附图中,选择的日期是 01/04,今天是 02/04。我希望看到 03/04(及以后)被禁用。理想情况下,就像您在图像中看到的“30”和“31”一样,它们是三月的最后几天。

这可能吗?如果相关,请使用 Delphi 7。

Delphi中的TDateTimePicker控件

4

2 回答 2

2

TDateTimePicker是 Win32 DTP 控件的包装器,它不提供您正在寻找的功能。没有自定义绘制下拉日历的选项,唯一可用的每日样式是normalbold

于 2015-04-02T17:05:09.070 回答
1

如前所述,评论和答案中提到的只有样式normal and bold可以使用。有了TYearBoldManager你就可以实现。

仅设置 3 月 30,31 日和 4 月 1,2,3,4

测试:win XP/3 上的 Delphi5

minDate = 2015/03/30maxDate = 2015/04/04

你可以设置bold日期

procedure TForm1.FormCreate(Sender: TObject);
begin
   MonthCalendar1.CalColors.MonthBackColor :=  $6A7678;
   MonthCalendar1.CalColors.TextColor := $4D5858;

   FYearBoldManager := TYearBoldManager.Create;
   FYearBoldManager.MakeBold(3, 30);
   FYearBoldManager.MakeBold(3, 31);
   FYearBoldManager.MakeBold(4, 1);
   FYearBoldManager.MakeBold(4, 2);
   FYearBoldManager.MakeBold(4, 3);
   FYearBoldManager.MakeBold(4, 4);
   ...
end;

然后您应该更改颜色值以获得最佳对比度。这里只是一个建议。

在此处输入图像描述

在此处输入图像描述

测试这里有 4 个文件,MonthCalendarDemo

更新 :

MonthCalendarDemo.dpr

program MonthCalendarDemo;

uses
  Forms,
  Unit1 in 'Unit1.pas' {Form1},
  UMonthBoldStorage in 'UMonthBoldStorage.pas';

{$R *.RES}

begin
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.

看看UMonthBoldStorage.pas它是怎么做的。


这里有什么区别?

在此处输入图像描述

专家们已经认识到了。

向右TDateTimePicker

在左边 aTMonthCalendar和 aTComboBox

优势:

  • 不需要 min-maxDate
  • 可以有days without logfile
  • 完全控制日历。
  • 大胆的日子很容易使用
  • 可以看到你点击的地方(看看漂亮的虚线边框25。但对日历没有影响)。
  • 如果您点击错误的日期,则不会消失。(可以随意点击,日历只会在您双击粗体时消失。这里:第 20 天和第 22 天)。

在此处输入图像描述

  • TComboBox可以在或内单击down-arrow或 焦点命中时ENTER打开日历,并通过日志文件将您带到最后一个日期。

在此处输入图像描述

在此处输入图像描述

  • 从那里您可以舒适地使用箭头键查看有日志文件的月份和日期。

在此处输入图像描述

所有描述都可以通过几行附加代码来完成

procedure TForm1.MonthCalendar1DblClick(Sender: TObject);
var
   year, month, day : Word;
begin
    DecodeDate(MonthCalendar1.Date,Year, Month, Day);
    if FYearBoldManager.GetDayStatus(month, day) then begin
       if ValidDate then MonthCalendar1.Visible:=False;
    end;
end;

procedure TForm1.MonthCalendar1Click(Sender: TObject);
var
   year, month, day : Word;
begin
   DecodeDate(MonthCalendar1.Date,Year, Month, Day);
   if FYearBoldManager.GetDayStatus(month, day) then begin
      lastValidDate := MonthCalendar1.Date;
      ValidDate:=True;
   end else begin
      MonthCalendar1.Date := lastValidDate;
      ValidDate:=False;
   end;
end;

function TForm1.getComboBoxText(var validText:AnsiString):Boolean;
var
actText :AnsiString;

begin
    if ComboBox1.Text = '' then  actText := validText else actText := ComboBox1.Text;
    Try
    MonthCalendar1.Date :=  StrToDateTime(Copy(actText,1,10));
    if actText <> validText then validText := actText;
    lastValidDate := MonthCalendar1.Date;
    ValidDate:=True;
    Result := True;
    except
      Result := False;
    end;
end;

procedure TForm1.ComboBox1Click(Sender: TObject);
begin
     if getComboBoxText(validText) then MonthCalendar1.Visible:=True;
end;

procedure TForm1.ComboBox1KeyUp(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
     if getComboBoxText(validText) then MonthCalendar1.Visible:=True;
end;
于 2015-04-02T21:19:41.163 回答