I'm trying to improve a GUI by reducing the amount of clicks needed to perform some actions. However, one VCL component that's bothering me is a TValueListEditor which contains a list of keys and values, all controlled by dropdowns. Selecting an options always requires three clicks, when only two are needed:

At this point in time, the topmost row has focus, and the value can be changed by using the dropdown (two clicks). However, when the user wants to edit a different key, he first has to change focus to that key before he can use the dropdown (three clicks).
Is there any way to show the dropdown arrow on all rows to prevent that extra click?
Here's a mockup example of what I want to achieve:

To show all the options from a dropdown list, use the options property. The property allows you to get all the options with length property. You can try to run the following code to get all the options from a drop-down list.
Unless 'All' is an option in the data sources that populate your dropdowns, you will have to do it a different way. I just did something similar last week in an app I am working on. What I did was to add a checkbox under my dropdown with the option to select 'All'.
For example, let’s say your Drop Down cell is Cell A9 and you want to give “customized” information in Cell A10. You can insert a Macro or Formula (depending on the number of options in your Drop Down tab) in Cell A10 to check A9 content and then show the right information in Cell A10.
The biggest drawback of this technique is that the cell to the right of the validation list cell must be blank, and also be about 18 pixels wide. If your drop-down validation lists are in an Excel Table, then you will have to insert a blank column.
uses
  Vcl.Themes;
type
  TValueListEditor = class(Vcl.ValEdit.TValueListEditor)
  private
    procedure DrawDropDownButton(ACol, ARow: Integer; ARect: TRect;
      AState: TGridDrawState);
    function MouseOverButton(X: Integer): Boolean;
  protected
    procedure DrawCell(ACol, ARow: Integer; ARect: TRect;
      AState: TGridDrawState); override;
    procedure DrawCellHighlight(const ARect: TRect; AState: TGridDrawState;
      ACol, ARow: Integer); override;
    procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X,
      Y: Integer); override;
  end;
{ TValueListEditor }
type
  TInplaceEditListAccess = class(Vcl.Grids.TInplaceEditList);
procedure TValueListEditor.DrawCell(ACol, ARow: Integer; ARect: TRect;
  AState: TGridDrawState);
begin
  inherited DrawCell(ACol, ARow, ARect, AState);
  DrawDropDownButton(ACol, ARow, ARect, AState);
end;
procedure TValueListEditor.DrawCellHighlight(const ARect: TRect;
  AState: TGridDrawState; ACol, ARow: Integer);
var
  R: TRect;
begin
  R := ARect;
  if ItemProps[ARow - FixedRows].HasPickList then
    Dec(R.Right, EditList.ButtonWidth);
  inherited DrawCellHighLight(R, AState, ACol, ARow);
  DrawDropDownButton(ACol, ARow, ARect, AState);
end;
procedure TValueListEditor.DrawDropDownButton(ACol, ARow: Integer;
  ARect: TRect; AState: TGridDrawState);
var
  Details: TThemedElementDetails;
begin
  if (ACol = 1) and (ARow >= FixedRows) and not (gdFocused in AState) and
    ItemProps[ARow - FixedRows].HasPickList then
  begin
    ARect.Left := ARect.Right - EditList.ButtonWidth;
    Details := StyleServices.GetElementDetails(tgDropDownButtonNormal);
    StyleServices.DrawElement(Canvas.Handle, Details, ARect);
  end;
end;
procedure TValueListEditor.MouseDown(Button: TMouseButton; Shift: TShiftState;
  X, Y: Integer);
var
  ACol: Integer;
  ARow: Integer;
begin
  inherited MouseDown(Button, Shift, X, Y);
  MouseToCell(X, Y, ACol, ARow);
  if (Button = mbLeft) and (ARow > FixedRows) and
    ItemProps[ARow - FixedRows].HasPickList and
    not EditList.ListVisible and MouseOverButton(X) then
  begin
    EditorMode := True;
    TInplaceEditListAccess(EditList).DropDown;
  end;
end;
function TValueListEditor.MouseOverButton(X: Integer): Boolean;
begin
  Result := (UseRightToLeftAlignment and (X < EditList.ButtonWidth)) or
    (not UseRightToLeftAlignment and (X > ClientWidth - EditList.ButtonWidth));
end;

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With