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