2008-10-10 10 views
2

J'ai une TListBox avec multiselect et ExtendedSelect tous les deux réglés sur true. Je dois pouvoir faire glisser plusieurs éléments dans la zone de liste pour les réorganiser. Mon problème est ce qui se passe lorsque l'utilisateur clique sur un élément déjà sélectionné sans maintenir la touche CTRL ou MAJ enfoncée.TListBox Problèmes de glisser-déposer avec MultiSelect

Cas 1: DragMode est défini sur dmManual La sélection est effacée avant la souris. Cela ne permettra pas de faire glisser plusieurs éléments.

Cas 2: DragMode est défini sur dmAutomatic L'événement MouseDown ne se déclenche jamais. La sélection n'est pas effacée, donc le glissement est OK, mais l'utilisateur ne peut pas effacer la sélection en cliquant sur l'un des éléments sélectionnés. Cela pose vraiment un problème si tous les éléments sont sélectionnés ou si l'élément suivant que l'utilisateur souhaite sélectionner fait partie de la sélection en cours.

Notez que ce problème se produit uniquement si vous affectez quelque chose à DragObject dans la procédure OnStartDrag. Je pense que le problème disparaîtrait si OnStartDrag ne démarre que lorsque l'utilisateur déplace la souris. J'ai Mouse.DragImmediate: = faux ensemble mais je reçois toujours le StartDrag déclenché dès que je clique sur un élément dans la zone de liste.

J'utilise Delphi 7 pour ce projet, mais je vois le même comportement en Delphi 2007.

Répondre

0

Je ne sais pas pourquoi cela fait une différence, mais si je change le DragObject pour être un TDrag Control ObjectEx (au lieu d'un TDragObjectEx), j'obtiens le comportement que je recherche. Le mode glisser est réglé sur Automatique.

J'ai essayé de regarder et de voir ce que cela affectait mais je ne pouvais pas le comprendre.

0

J'ai joué avec pendant un certain temps. Et observez les mêmes effets.

Je voudrais utiliser Case2 et ajouter un bouton (Sélectionner tout/Désélectionner tout) à la liste. Il ajoute même des fonctionnalités supplémentaires et résout la partie la plus ennuyeuse du problème.

0

Utilisez le cas 2 et lorsque l'événement TListBox.OnMouseUp se déclenche, vérifiez si plusieurs éléments sont sélectionnés et ont été déplacés. Si plusieurs éléments sont sélectionnés mais n'ont pas été déplacés, désélectionnez tous les éléments en dehors de l'élément sur lequel vous avez cliqué.

Je voudrais utiliser cette méthode parce que l'Explorateur Windows fonctionne de cette façon.

0

Bit d'un kludge mais cela fonctionne. DragMode sur ListBox est défini sur dmAutomatic.

procedure TForm1.ListBox1DragDrop(Sender, Source: TObject; X, Y: Integer); 
var 
    iDropIdx, i: Integer; 
    pDropPoint: TPoint; 
    slSelected: TStrings; 
begin 
    {Which item is being dropped onto?} 
    pDropPoint := Point(X, Y); 
    iDropIdx := ListBox1.ItemAtPos(pDropPoint, False); 

    slSelected := TStringList.Create; 
    try 
    {Copy the selected items to another string list} 
    for i := 0 to Pred(ListBox1.Items.Count) do 
    begin 
     if (ListBox1.Selected[i]) then 
     slSelected.Append(ListBox1.Items[i]); 
    end; 

    {Find the selected items in the listbox and swap them with the drop target} 
    for i := 0 to Pred(slSelected.Count) do 
    begin 
     ListBox1.Items.Exchange(ListBox1.Items.IndexOf(slSelected[i]), iDropIdx); 
     inc(iDropIdx); 
    end; 
    finally 
    slSelected.Free; 
    end; 
end;