由于 TDateTimePicker 只能用于日期或时间,不能同时使用。如果将Kind属性设置为dtkDate,则可以指定自定义DATE格式,但忽略任何TIME格式,并且Time未定义使用该属性。如果将Kind属性设置为dtkTime,则可以指定自定义TIME格式,但忽略任何DATE格式,并且Date未定义使用该属性。虽然通过设置 Format = 'yyyy/MM/dd HH:mm:ss' 可以显示日期和时间,但读取到 DateTime 的值是初始化前的,无法正确读取出日期和时间。
很多时候,需要同时显示日期和时间,又不想使用两个控件组合显示,如何实现呢?
方法一:通过修改 TDateTimePicker 的源码实现,打开 Vcl.ComCtrls.pas 大约 28144 行:
procedure TDateTimePicker.CNNotify(var Message: TWMNotifyDT);
try DT := SystemTimeToDateTime(st); if Kind = dtkDate then SetDate(DT) else SetTime(DT); // 增加一行 SetDateTime(DT); finally FChanging := False; end;
然后重新编译这个单元,生成dcu文件,替换原有的,或者是将这个修改的单元添加到自己的工程中。
方法二:基于TDateTimePicker派生新的控件。
unit uZDateTimePicker; interface uses Vcl.ComCtrls, SysUtils; type TZDateTimePicker = class(TDateTimePicker) private procedure SetDateAndTime; protected procedure Change; override; end; implementation { TZDateTimePicker } procedure TZDateTimePicker.Change; begin SetDateAndTime end; procedure TZDateTimePicker.SetDateAndTime; begin DateTime := StrToDateTime(Caption); inherited; end; end.
方法三:通过读取TDateTimePicker私有属性实现。
// this class is just to access protected Caption property THackDateTimePicker = class(TDateTimePicker);
这样使用
procedure TForm1.DateTimePicker1Change(Sender: TObject); begin TDateTimePicker(Sender).DateTime := StrToDateTime(THackDateTimePicker(Sender).Caption); end;
上面三种方法各有优缺点,我个人更喜欢第三种。