2012-10-21 20 views
6

我試圖通過減少執行某些操作所需的點擊量來改進GUI。然而,一個困擾我的VCL組件是一個TValueListEditor,它包含一個鍵和值列表,全部由下拉列表控制。選擇一個選項總是需要三次點擊,只需要兩個條件:總是在TValueListEditor中顯示選項下拉列表

Bad

在這個時間點上,最上面一排具有焦點,並且該值可以使用下拉(兩次點擊)來改變。但是,當用戶想要編輯不同的密鑰時,他必須首先將焦點更改爲該密鑰才能使用下拉列表(三次點擊)。

有什麼辦法顯示所有行上的下拉箭頭以防止額外點擊?

這裏是什麼,我想實現一個樣機例如:

Good

+1

可以的OnMouseMove事件更好的解決方案將集行重點是什麼? – teran

回答

8
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; 

enter image description here

+0

這似乎工作得很好。一個側面說明(我忘記了一些細節):我使用Delphi 7,它將主題服務聲明爲'ThemeServices'而不是'StyleServices',它不公開'DrawCellHighlight',它將下拉箭頭定義爲'tcDropDownButtonNormal'從此,這是一個很好的解決方案。 – Orwell

+0

我可以提出改進建議嗎?至少在Delphi 7中,當這個組件被添加到調色板並用於設計表單時,EditList可能並不總是被分配,導致相當多的錯誤。我建議將「Assigned(EditList)」的檢查添加到任何使用它的地方。 – Orwell

+0

@Orwell我沒有設計或測試它作爲組件安裝。但是你可以/可以在這裏自己改變它。也許可以添加一個相應的屬性呢? – NGLN

相關問題