Delphi XE4检测TlistGroup之间的项目切换

Delphi XE4检测TlistGroup之间的项目切换,delphi,listview,delphi-xe4,Delphi,Listview,Delphi Xe4,我已经使用Delphi XE4一周了,我刚刚发现了新的TListGroups功能。设置TlistItem的GroupID可以轻松地在组之间切换/移动。现在,我想让一个过程在TListItem离开组和/或TListItem进入组时调用。我在找这样的东西: procedure TForm1.ListView1On(Before/After)ListGroupEnter(Sender: TObject; Item: TListItem); begin // Do some stuff here li

我已经使用Delphi XE4一周了,我刚刚发现了新的
TListGroups
功能。设置
TlistItem
GroupID
可以轻松地在组之间切换/移动。现在,我想让一个过程在
TListItem
离开组和/或
TListItem
进入组时调用。我在找这样的东西:

procedure TForm1.ListView1On(Before/After)ListGroupEnter(Sender: TObject; Item: TListItem);
begin
 // Do some stuff here like...
 // AllowedToDraw := TRUE/FALSE
 // I/O Code...
 // etc...
end;

procedure TForm1.ListView1On(Before/After)ListGroupLeave(Sender: TObject; Item: TListItem);
begin
 // Do some stuff here like...
 // This might be replaceable with OnDeletion...
 // I/O Code...
end;
这里的主要问题是,如果设置
GroupID
属性,则检测不同组之间的切换。
因此,在您更改/设置
GroupID
属性时,是否有任何东西可以检测开关?

属性设置器将
LVM\u SETITEM
消息发送到
TListView的
HWND。您可以对
TListView
进行子类化,并在
TListView
处理该消息之前拦截该消息,例如:

const
  APPWM_LISTVIEW_CHECKGROUP = WM_APP + 100;

var
  PrevLVWndProc: TWndMethod = nil;

procedure TForm1.FormCreate(Sender: TObject);
begin
  PrevLVWndProc := ListView1.WindowProc;
  ListView1.WindowProc := LVWndProc;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  ListView1.WindowProc := PrevLVWndProc;
end;

procedure TForm1.LVWndProc(var Message: TMessage);
var
  LVItem: PLVItem;
  ListItem: TListItem;
begin
  case Message.Msg of
    LVM_SETITEM:
    begin
      LVItem := PLVItem(Message.LParam);
      if (LVItem^.mask and LVIF_GROUPID) <> 0 then
      begin
        ListItem := ListView1.Items[LVItem.iItem];

        if ListItem.GroupID <> LVItem.iGroupID then
        begin
          if ListItem.GroupID >= 0 then
            ListView1GroupLeave(ListView1, ListItem);

          PrevLVWndProc(Message);

          // this gives the TListItem time to actually update itself
          PostMessage(ListView1.Handle, APPWM_LISTVIEW_CHECKGROUP, 0, LVItem.iItem);

          Exit;
        end;
      end;
    end;
    APPWM_LISTVIEW_CHECKGROUP:
    begin
      ListItem := ListView1.Items[Message.LParam];
      if ListItem.GroupID >= 0 then
        ListView1GroupEnter(ListView1, ListItem);
      Exit;
    end;
  end;

  PrevLVWndProc(Message);
end;

procedure TForm1.ListView1GroupLeave(Sender: TObject; Item: TListItem);
begin
  // Item is about to leave from its current GroupID ...
end;

procedure TForm1.ListView1GroupEnter(Sender: TObject; Item: TListItem);
begin
  // Item has entered into its current GroupID ...
end;    
const
APPWM_LISTVIEW_CHECKGROUP=WM_APP+100;
变量
PrevLVWndProc:TWndMethod=nil;
过程TForm1.FormCreate(发送方:TObject);
开始
PrevLVWndProc:=ListView1.WindowProc;
ListView1.WindowProc:=LVWndProc;
结束;
程序TForm1.FormDestroy(发送方:ToObject);
开始
ListView1.WindowProc:=PrevLVWndProc;
结束;
过程TForm1.LVWndProc(变量消息:TMessage);
变量
LV项目:PLVItem;
列表项:TListItem;
开始
case Message.Msg of of
LVM_设置项:
开始
LVItem:=PLVItem(Message.LParam);
如果(LVItem^.mask和LVIF_GROUPID)0,则
开始
ListItem:=ListView1.Items[LVItem.iItem];
如果ListItem.GroupID为LVItem.igGroupId,则
开始
如果ListItem.GroupID>=0,则
ListView1GroupLeave(ListView1,ListItem);
PrevLVWndProc(消息);
//这给了TListItem实际更新自身的时间
PostMessage(ListView1.Handle,APPWM_LISTVIEW_CHECKGROUP,0,LVItem.iItem);
出口
结束;
结束;
结束;
APPWM_列表视图_检查组:
开始
ListItem:=ListView1.Items[Message.LParam];
如果ListItem.GroupID>=0,则
ListView1GroupCenter(ListView1,ListItem);
出口
结束;
结束;
PrevLVWndProc(消息);
结束;
程序TForm1.ListView1GroupLeave(发件人:ToObject;项目:TListItem);
开始
//项目即将从其当前组ID离开。。。
结束;
过程TForm1.ListView1GroupEnter(发送方:ToObject;项:TListItem);
开始
//项目已输入其当前组ID。。。
结束;

它需要截获
TListItem.SetGroupID
setter。最好创建自己的助手函数,然后将
GroupID
设置为其中的项目。我不知道它是如何处理组开关的。它是否完全删除该项,然后将其重新添加到另一个组中?
GroupID
setter只设置表示该项的结构的
iGroupId
成员。剩下的取决于系统。所以我想没有简单的方法可以做到这一点。不,这里没有太多的选择。您可以截取该setter,或生成一个函数(例如,截取的
TListItem
类的方法)。此函数将能够触发您自己的事件,并设置item.Works的
GroupID
。非常感谢你。他们需要在未来的embarcadero产品中添加此功能。