首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >忽略单击TListView复选框

忽略单击TListView复选框
EN

Stack Overflow用户
提问于 2013-10-28 13:57:52
回答 3查看 3.6K关注 0票数 3

我有一个TListview,其中我想使用复选框来指示某个事件是否发生在列表中的某一项上。

我可以读取和设置复选框状态,但我真正想要做的是禁用用户使用鼠标单击更改状态的能力。

对于TCheckList,我可以使用OnClickCheck将checked状态设置为逆

对于一个TListview来说,同样的情况并不适用。此时,我可以看到复选框已在OnMouseDown中被锁定,但无法禁用单击。

代码语言:javascript
复制
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;

有什么建议吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-10-28 17:30:06

使用事件Onchanging并将AllowChange设置为False

代码语言:javascript
复制
procedure TForm1.ListView1Changing(Sender: TObject; Item: TListItem;
  Change: TItemChange; var AllowChange: Boolean);
begin
  AllowChange := False;
end;

Update: OP希望用户能够选择项目。所以,也许,使用OnItemChecked事件进行一点攻击就可以了。

代码语言:javascript
复制
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:使用此技巧的问题是,在更改任何项状态之前必须禁用它。例如:

代码语言:javascript
复制
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;
票数 3
EN

Stack Overflow用户

发布于 2013-10-29 20:15:30

您可以挂起窗口proc,在进行任何VCL事件处理之前强制进行项选中状态:

代码语言:javascript
复制
  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;
票数 1
EN

Stack Overflow用户

发布于 2017-05-25 12:28:34

或者你可以这样做:

代码语言:javascript
复制
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;

List是您的TListView,CheckBoxesEnabled是启用或禁用复选框的布尔变量。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19636713

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档