2014-09-19 115 views
0

我試圖切換TCheckListBox項目狀態,因此如果選中它,則取消選中它,反之亦然。這通常只在您點擊物理盒本身時纔會切換,但我希望它在用戶單擊項目行上的任意位置時切換。單擊CheckListBox項目以切換該項目的檢查狀態

下面的代碼可以工作,但是現在可以防止物品在物理框中單擊時可以切換(例如,如果當前未選中,那麼它們會在框中單擊,並保持未選中狀態)。

是否有可能在代碼中同時存在兩種行爲或錯誤?

procedure TMainFrm.CheckListBoxModulesMouseDown(Sender: TObject; 
    Button: TMouseButton; Shift: TShiftState; X, Y: Integer); 
var 
    APoint: TPoint; 
    Index: integer; 
begin 
    if (Button = mbLeft) then 
    begin 
    APoint.X := X; 
    APoint.Y := Y; 
    Index := CheckListBoxModules.ItemAtPos(APoint, True); 

    if(Index > -1) then 
    begin 
     CheckListBoxModules.Checked[Index] := not CheckListBoxModules.Checked[Index]; 
    end;  
    end;  
end; 
+1

類似於'如果y> 16然後開始...結束' – bummi 2014-09-19 22:41:08

+0

嗯我想這是有效的。 X確實。 – ikathegreat 2014-09-19 22:52:27

回答

1

你的問題是,在你切換狀態後,盒子本身會在檢查命中後再次切換它。

一個解決辦法是取消這個內置的檢查行爲:

procedure TMainFrm.CheckListBoxModulesClickCheck(Sender: TObject); 
begin 
    CheckListBoxModules.Checked[CheckListBoxModules.ItemIndex] := 
     not CheckListBoxModules.Checked[CheckListBoxModules.ItemIndex]; 
end; 


這工作,因爲當您通過代碼更改檢查狀態OnClickCheck不被解僱。只有在複選框中鼠標點擊導致的狀態變化纔會顛倒過來。


更好的解決方案是當點擊複選框時不切換狀態。如果您決定實施此解決方案,請參閱TCheckListBox.GetCheckSize中的代碼,瞭解VCL如何確定複選框大小以及TCheckListBox.MouseDown確定位置的方式。

1

這是一種點擊測試幫助點的情況。如果用戶點擊複選框,則不要手動切換檢查狀態。您可以使用類似TCheckListBox內部使用的邏輯來確定用戶是否在複選框上單擊。如果鼠標位於複選框上,讓TCheckListBox處理點擊。否則,請手動切換。例如:

type 
    TCheckListBoxAccess = class(TCheckListBox) 
    end; 

procedure TMainFrm.CheckListBoxModulesMouseDown(Sender: TObject; Button: TMouseButton; 
    Shift: TShiftState; X, Y: Integer); 
var 
    Index: Integer; 

    procedure DoToggle; 
    var 
    State: TCheckBoxState; 
    begin 
    if (Index >= 0) and (Index < CheckListBoxModules.Items.Count) and CheckListBoxModules.ItemEnabled[Index] then 
    begin 
     State := CheckListBoxModules.State[Index]; 
     case State of 
     cbUnchecked: 
      if CheckListBoxModules.AllowGrayed then State := cbGrayed else State := cbChecked; 
     cbChecked: State := cbUnchecked; 
     cbGrayed: State := cbChecked; 
     end; 
     CheckListBoxModules.State[Index] := State; 
     TCheckListBoxAccess(CheckListBoxModules).ClickCheck; 
    end; 
    end; 

begin 
    if Button = mbLeft then 
    begin 
    Index := CheckListBoxModules.ItemAtPos(Point(X,Y),True); 
    if (Index <> -1) and CheckListBoxModules.ItemEnabled[Index] then 
     if not TCheckListBoxAccess(CheckListBoxModules).UseRightToLeftAlignment then 
     begin 
     if X - CheckListBoxModules.ItemRect(Index).Left >= TCheckListBoxAccess(CheckListBoxModules).GetCheckWidth then 
      DoToggle; 
     end 
     else 
     begin 
     Dec(X, CheckListBoxModules.ItemRect(Index).Right - TCheckListBoxAccess(CheckListBoxModules).GetCheckWidth); 
     if (X <= 0) or (X >= TCheckListBoxAccess(CheckListBoxModules).GetCheckWidth) then 
      DoToggle; 
     end; 
    end; 
end; 
0

我已經給Sertac的答案添加了一些代碼,以檢查按下的女巫鍵,以便我們也可以使用鍵盤上下移動。

procedre TfrmRelBalanceteGerencial.cklGrupoContasClick(Sender: TObject); 
begin 
inherited; 
    if HiWord(GetKeyState(VK_UP)) <> 0 or HiWord(GetKeyState(VK_DOWN)) then 
    begin 
    // do nothing 
    end 
    else 
    begin 
    cklGrupoContas.Checked[cklGrupoContas.ItemIndex] := not cklGrupoContas.Checked[cklGrupoContas.ItemIndex]; 
    end; 
end;