2013-10-28 29 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。