6
votes

I am working on an application where i have a combobox with long text values.Since the text values are large(in term of characters ..20 or more), to display in the combobox, the requirement was to display on the first character after selecting from the drop down. Like in the image marked in red. if the user selects 3th item 3 0.5 to 1.25 Slight i should only display the 3 in the combobox.

enter image description here

So i tried this

   sTheSelectedValue : string;

  procedure TForm1.ComboBox1Select(Sender: TObject);
  begin
   sTheSelectedValue:=TrimTextAndDisplay(ComboBox1.Text); //send theselected value
   ComboBox1.Text :='';                                   //clear the selection
   ComboBox1.Text:=sTheSelectedValue;                     //now assign as text to combo box   
   Button1.Caption:=ComboBox1.Text;                      //just show the new value on the button.
  end;


   function TForm1.TrimTextAndDisplay(TheText : string): string;
   var
   sTheResult : string;
     begin
        sTheResult :=copy(TheText,0,1); //extract the first value..
        Result     :=sTheResult;
     end;

The result is enter image description here

The button seem to show the proper value but not the combobox.

what i want is to get 3 in the combobox, i cant seem set ComboBox1.Text:= can any one tell me how to do it? like this on selection of from the combobox the result should be enter image description here

2

2 Answers

13
votes

I would suggest owner-drawing the ComboBox to handle this. Set the TComboBox.Style property to csOwnerDrawFixed, then store just the numbers '1', '2', '3', etc in the TComboBox.Items property itself and use the TComboBox.OnDrawItem event to render the full strings when the drop-down list is visible, eg:

var
  sTheSelectedValue : string; 

const
  ItemStrings: array[0..7] of string = (
    '0 to 0.1 Calm (rippled)',
    '0.1 to 0.5 Smooth (wavelets)',
    '0.5 to 1.25 Slight',
    '1.25 to 2.5 Moderate',
    '2.5 to 4 Rough',
    '4 to 6 Very rough',
    '6 to 9 High',
    '9 to 14 Very high');

procedure TForm1.FormCreate(Sender: TObject);
var
  I: Integer;
begin
  ComboBox1.Items.BeginUpdate;
  try
    for I := Low(ItemStrings) to High(ItemStrings) do begin
      ComboBox1.Items.Add(IntToStr(I+1));
    end;
  finally
    ComboBox1.Items.EndUpdate;
  end;
end; 

procedure TForm1.ComboBox1Select(Sender: TObject); 
begin 
  sTheSelectedValue := IntToStr(ComboBox1.ItemIndex+1);
  Button1.Caption := sTheSelectedValue;
end; 

procedure TForm1.ComboBox1DrawItem(Control: TWinControl; Index: Integer; Rect: TRect; State: TOwnerDrawState);
var
  s: String;
begin
  if odSelected in State then begin
    ComboBox1.Canvas.Brush.Color := clHighlight;
    ComboBox1.Canvas.Font.Color := clHighlightText;
  end else begin
    ComboBox1.Canvas.Brush.Color := ComboBox1.Color;
    ComboBox1.Canvas.Font.Color := ComboBox1.Font.Color;
  end;
  ComboBox1.Canvas.FillRect(Rect);
  s := IntToStr(Index+1);
  if not (odComboBoxEdit in State) then begin
    s := s + ' ' + ItemStrings[Index];
  end;
  ComboBox1.Canvas.TextRect(Rect, Rect.Left+2, Rect.Top+2, s);
  if (State * [odFocused, odNoFocusRect]) = [odFocused] then begin
    ComboBox1.Canvas.DrawFocusRect(Rect);
  end;
end;
-1
votes

You have to try to save the data in a record, for ex:

 type
 TMyRec = record
  Num:Integer;
  Text:String;
end;

TMyRecArray = array of TMyRec;

MyRecArray:TMyRecArray;

then you can set manually the items to be set in the ComboBox (on the OnFromCreate),

SetLength(MyRecArray,9);
MyRecArray[0].Num:=1;
MyRecArray[0].Text:='0 to 0.1 Calm Rippled';
.
.

and so on.

then in the combobox strigns place only the numbers, and

procedure TForm1.ComboBox1Select(Sender: TObject);   
var
  i:integer;     
begin         
  for i:=0 to 9 do
  begin
    if ComboBox1.Text=IntToStr(MyRecArray[i].Num) then
      Button1.Caption:=MyRecArray[i].Text; 
  end;
end;