2013-05-15 2 views
4

Я использую Delphi XE4 уже неделю, и я только что открыл новую функцию TListGroups. Легко установить TlistItemGroupID, чтобы легко переключаться между группами. Теперь я хотел бы иметь процедуру, которая вызывает, как только TListItem УДАЛЯЕТ группу и/или как только TlistItem ВХОДИТ в группу. Я ищу что-то вроде этого:Delphi XE4 обнаруживает переключатель предметов между TListGroups

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?

+1

Было бы нужно перехватить 'TListItem.SetGroupID' сеттера. Лучше сделайте свою собственную вспомогательную функцию и установите «GroupID» на элементы оттуда. – TLama

+0

Я точно не знаю, как это относится к групповому коммутатору tho. Удаляет ли элемент полностью, а затем повторно добавляет его в другую группу? –

+1

Наборщик GroupID просто устанавливает член 'iGroupId' из [' LVITEM'] (http://msdn.microsoft.com/en-us/library/windows/desktop/bb774760 (v = vs.85). aspx), которая представляет элемент. Остальное - система. – TLama

ответ

4

TListItem.GroupID Идентификатор имущества отправляет сообщение LVM_SETITEM на номер TListView's 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;  
+0

Работы. Большое спасибо. Им нужно добавить это в будущие продукты embarcadero. –

Смежные вопросы