2

I have a form with two TAdvDateTimePicker components, and few other edits (in delphi XE7). Both datetime fields are optional, so if the user don't want to fill them, in the database will both be null.

Problem is, that unlike for example good old TDateEdit, the TAdvDateTimePicker does not accept a blank value even as default. I know, that something like "null datetime" does not exist, but I need to know, if user did or did not want to fill those dates. So leaving today's date as default, and using onChange, onEnter or whatever action to check if a value has been set, isn't a solution - he may want to use today's date, so he leaves it like that.

There is of course a possibility to set the default value to, let's say 1.1.1900 (an obvious nonsense) and then check if it has changed, but that is the last thing I would like to do. Is there a better way?

Thanks

j.kaspar
  • 751
  • 1
  • 11
  • 29
  • Check box titled "date is null" – David Heffernan Mar 13 '16 at 18:37
  • It also is a solution, yes, but it would be a little confusing for the user. He doesn't know (and doesn't have to know) the limitations of used components... He just needs to fill a simple form and if he does not explicitly want to fill the dates, he does't want to think about them at all. – j.kaspar Mar 13 '16 at 18:46
  • I was trying to give you a solution that works, because the control doesn't support null values – David Heffernan Mar 13 '16 at 18:55
  • I know, thank you. If there is no possible workaround, that will not affect an user, then I will have to use different component... – j.kaspar Mar 13 '16 at 18:57
  • 1
    `SendMessage(Picker.Handle, DTM_SETFORMAT, 0, LPARAM(fmt))` where fmt is a space (' ') if TAdvDateTimePicker derives from a TDateTimePicker. – Sertac Akyuz Mar 13 '16 at 19:08
  • Nice! It derives from TDateTimePicker and it works, but I am not successfull in returning to original format when I need to fill a real value. I tried: `fmt := 'dd.MM.yyyy'; SendMessage(DateTimePicker1.Handle, DTM_SETFORMAT, 0, DWORD(fmt));` plus few other formats in onEnter event, but it only lets me to fill a day. No moth, no year. – j.kaspar Mar 13 '16 at 19:28
  • 1
    Just use an empty string to revert: `SendMessage(Picker.Handle, DTM_SETFORMAT, 0, LPARAM(Pointer(PChar(''))))` – Sertac Akyuz Mar 13 '16 at 19:30
  • Great! Thank you very much! – j.kaspar Mar 13 '16 at 19:33
  • 1
    @j.kaspar - You're welcome. Just noticed, VCL does "setformat", it's the Format property, no need to SendMessage... – Sertac Akyuz Mar 13 '16 at 19:35
  • There are many dupes from other languages, for instance http://stackoverflow.com/questions/846395/how-can-i-make-a-datetimepicker-display-an-empty-string – David Heffernan Mar 13 '16 at 20:23

1 Answers1

2

With thanks to Sertac Akyuz, here is the simplest solution:

onActivate of the form, set .Format property to a space (' '):

procedure TfrmDeliveriesEdit.FormActivate(Sender: TObject);
begin
  DateTimePicker1.Format:= ' ';
end;

Then, onEnter of the picker, set the format to empty string ('') to revert back, if the user wants to fill a real value

procedure TfrmDeliveriesEdit.DateTimePicker1Enter(Sender: TObject);
begin
  DateTimePicker1.Format:= '';
end;

Edit: to return back to "null" value, check delete key in onKeyDown event like this:

procedure TfrmDeliveriesEdit.dpTaxDateKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if Key = VK_DELETE then dpTaxDate.Format:= ' ';
end;
j.kaspar
  • 751
  • 1
  • 11
  • 29