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

StackOverflow https://stackoverflow.com/questions/12416696

  •  01-07-2021
  •  | 
  •  

Question

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?

Was it helpful?

Solution 2

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.

OTHER TIPS

What about ownerdraw the TCombobox?

procedure TForm16.cbLongDateFormatDrawItem(Control: TWinControl; Index: Integer;
  Rect: TRect; State: TOwnerDrawState);
begin
  with Control as TComboBox do
  begin
    if not (odSelected in State) then
      Canvas.Brush.Color:=clWindow
    else
      Canvas.Brush.Color:=clHighlight;
    Canvas.FillRect(Rect);
    Canvas.TextOut(Rect.Left +2 , Rect.Top, FormatDateTime(cbLongDateFormat.Items[Index], Now));
  end;
end;

procedure TForm16.FormCreate(Sender: TObject);
begin
  cbLongDateFormat.Items.Add('ddddd');
  cbLongDateFormat.Items.Add('dddddd');
  cbLongDateFormat.Items.Add('dd/mm/yyyy');
  cbLongDateFormat.Items.Add('d mmmm yyyy');
end;

enter image description here

Store your date/time format strings in a separate TStringList, then in the TComboBox.OnChange event, you can use the TComboBox.ItemIndex property to know which drop-down list item was selected so you can assign the corresponding TStringList item to the TComboBox.Text property.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top