2013-10-28 30 views
2

我有一個TListview我想使用複選框來指示事件是否發生在列表中的項目。忽略點擊TListView複選框

我可以讀取並設置複選框狀態,但我真正想要做的是禁用用戶通過單擊鼠標來更改狀態的功能。

對於TCheckList我可以checked狀態設置爲使用OnClickCheck

同爲一TListview不起作用倒數。在這些時刻,我可以看到,該複選框已被OnMouseDown目標,但不能從經歷禁用點擊..

procedure TMF.ListViewMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); 
var 
    MyHitTest : THitTests; 
begin 
    MyHitTest := (Sender as TListView).GetHitTestInfoAt(X,Y); 
    if htOnStateIcon in MyHitTest then 
     (Sender as TListView).OnMouseDown := nil; 
end; 

建議?

+0

是否將TListView的Enabled屬性設置爲false幫助? –

+0

沒有。我需要單獨點擊項目(正在使用'Rowselect'),只需複選框的狀態在我的控制下 –

+4

您正在與此係統打交道。它不想讓你這樣做。在你的位置上,我會尋找一個不涉及內置複選框的解決方案。 –

回答

2

使用事件Onchanging並將AllowChange設置爲False

procedure TForm1.ListView1Changing(Sender: TObject; Item: TListItem; 
    Change: TItemChange; var AllowChange: Boolean); 
begin 
    AllowChange := False; 
end; 

更新:OP希望用戶能夠選擇該項目。所以,也許,使用OnItemChecked事件可以做一點小事。

procedure TForm1.ListView1ItemChecked(Sender: TObject; Item: TListItem); 
begin 
    if TComponent(Sender).Tag = 0 then 
    begin 
    TComponent(Sender).Tag := 1; 
    Item.Checked := not Item.Checked; 
    TComponent(Sender).Tag := 0; 
    end; 
end; 

UPDATE2:使用這一招的問題是,您更改項目狀態之前,必須將其禁用。例如:

Procedure LoadListViewItems; 
begin 
    //Let's permit modification in ListView Items. 
    ListView1.OnItemChecked := nil; 
    try 
    //put Load Items code Here! 
    finally 
    //User cannot change Items statuses 
    ListView1.OnItemChecked := ListView1ItemChecked; 
    end; 
end; 
+0

你應該先檢查'Change'參數,然後再盲目地禁止所有的改變:'如果Change = ctState然後AllowChange:= False;' –

+0

試過這樣可以防止被選中的行被選中,因爲ctState覆蓋選中/未選中以及複選框狀態變化。我試着給OnMouseDown添加一個booelan,但是在* OnChanging之後被解僱了...... –

+0

@RemyLebeau除了這只是一個例子,我不明白爲什麼。如果他不想隨時做出改變,有什麼不同? – EMBarbosa

1

你可以掛鉤的窗口過程,迫使該項目之前的任何VCL事件處理選中狀態發生:

TForm1 = class(TForm) 
    ... 
    private 
    fLVWndProc: TWndProc; 
    end; 


    procedure TForm1.FormCreate(Sender: TObject); 
    begin 
    // Save the original window proc and install the hook 

    fLVWndProc := Listview1.WindowProc; 
    Listview1.WindowProc := LVWndProcHook; 
    end; 



    procedure TForm1.LVWndProcHook(var aMessage: TMessage) ; 
    var 
    notify: PNMListView; 
    bItemState: Boolean; 
    begin 
    if (aMessage.Msg = CN_NOTIFY) 
    and (PNMHdr(aMessage.LParam).Code = LVN_ITEMCHANGED) then 
    begin 
     notify := PNMListView(aMessage.LParam); 

     if ((notify.uChanged and LVIF_STATE) <> 0) then 
     begin 
     // Determine actual item state and re-apply it before continuing 
     bItemState := GetUnderlyingItemState(notify.iItem); 
     ListView_SetCheckState(notify.hdr.hwndFrom, notify.iItem, bItemState); 
     end; 
    end; 

    //original ListView message handling 
    fLVWndProc(aMessage) ; 
    end; 
0

或者你可以這樣做:

procedure TForm1.ListItemChecked(Sender: TObject; Item: TListItem); 
begin 
if not CheckBoxesEnabled then begin 
    List.OnItemChecked:=nil; 
    Item.Checked:=not Item.Checked; 
    List.OnItemChecked:=ListItemChecked; 
end; 
end; 

列表是您的TListView和CheckBoxesEnabled一個布爾變量,用於啓用或禁用checkbo XES。