delphitcombobox

In a TComboBox, how can I have the dropdown display X, but the text property gets Y when X is picked?


I need the user to pick a date format (dd/mm/yyyy or dd mmmm yyyy etc...) but displaying these options is just confusing. What I want to be able to do is have the TComboBox items filled with "14/09/2012", "14 September 2012", "Friday 14 September 2012" etc, and when the user picks one of these date formats the combobox gets the text "dd mmmm yyyy" or whatever the date format is (although I still want them to be able to type in something else such as "d/m/yy").

However I haven't found an easy way of doing this - other than a TEdit with a TSpeedButton which opens a form with the selection options in it which is my second choice if there is no way to do this with a TComboBox.

Question: How can I have a TComboBox dropdown display dates, but the text property gets the date format when a date is picked?


Solution

  • It is not possible to directly do this via the OnChange event on the ComboBox, as after the OnChange event the text property gets set back to whatever was picked by the user. However I can send a message to the form to make the change.

    procedure TfINISettings.cbLongDateFormatChange(Sender: TObject);
    begin
      PostMessage(Handle, WM_USER, 0, 0);
    end;
    

    and in the form interface declare a procedure

    procedure DateFormatComboBoxChange(var msg: TMessage); message WM_USER;
    

    to handle this message, and in the implementation

    procedure TfINISettings.DateFormatComboBoxChange(var msg: TMessage);
    begin
      if cbLongDateFormat.ItemIndex <> -1 then
        cbLongDateFormat.Text := DateFormats[cbLongDateFormat.ItemIndex];
    end;
    

    Where DateFormats is a TStringList that contains my date formats. The FormCreate method looks like this

    procedure TfINISettings.FormCreate(Sender: TObject);
    var
      d: String;
    begin
      DateFormats := TStringList.Create;
      DateFormats.Add('ddddd');
      DateFormats.Add('dddddd');
      DateFormats.Add('d mmmm yyyy');
      for d in DateFormats do
        cbLongDateFormat.Items.Add(FormatDateTime(d, now));
    end;
    

    Suggestions on improvements welcome.