ListBox Drag&Drop Multiple [Résolu]

Signaler
Messages postés
67
Date d'inscription
mercredi 30 juin 2004
Statut
Membre
Dernière intervention
6 octobre 2011
-
Messages postés
67
Date d'inscription
mercredi 30 juin 2004
Statut
Membre
Dernière intervention
6 octobre 2011
-
Bonsoir,
joyeuses fêtes a tout le monde.

Comment peut on faire un un drag and drop d'une selection multiple dans une listbox?

Merci d'avance

morinxav

14 réponses

Messages postés
2527
Date d'inscription
jeudi 15 janvier 2004
Statut
Membre
Dernière intervention
16 octobre 2019
14
Joyeuses fêtes à toutes et tous, too!

Voilà un bout de code pour te montrer la façon de procéder.
Je n'ai pas le temps de l'optimiser ni de commenter. Désolé.

var   ListeItems: TStrings;



procedure TForm1.FormCreate(Sender: TObject);
  begin
  ListBox1.MultiSelect       := true;
  ListBox1.ExtendedSelect := true;
  ListeItems := TStringList.Create;
end;



procedure TForm1.FormDestroy(Sender: TObject);
  begin
  ListeItems.Free;
end;



procedure TForm1.ListBox1DragOver(Sender, Source: TObject; X, Y: Integer;
  State: TDragState; var Accept: Boolean);
  var   i : Integer;
  begin
  (Sender as TControl).begindrag(false,3);
  ListeItems.Clear;
  for i := 0 to ListBox1.Count - 1 do
    if ListBox1.Selected[i] then ListeItems.Add(IntToStr(i));
end;



procedure TForm1.ListBox2DragOver(Sender, Source: TObject; X, Y: Integer;
  State: TDragState; var Accept: Boolean);
  begin
  Accept := true;
end;



procedure TForm1.ListBox2DragDrop(Sender, Source: TObject; X, Y: Integer);
  var   i : Integer;
  begin
  for i := 0 to ListeItems.Count - 1 do
      ListBox2.Items.Add(ListBox1.Items[StrToInt(ListeItems[i])]);
  for i := ListeItems.Count - 1 downto 0 do
      ListBox1.Items.Delete(StrToInt(ListeItems[i]));
end;

On peut faire un Drag'n Drop des éléments sélectionnés de ListBox1 vers ListBox2.
A toi d'arranger ça à ta sauce   ;)

@+
Messages postés
1721
Date d'inscription
vendredi 27 décembre 2002
Statut
Modérateur
Dernière intervention
30 août 2020
3
Salut à tous,

Il n'est pas obligatoire de passer par un TStrings.
Dans l'exemple qui suit, on peut indifféremment glisser-déposer depuis ListBox1 vers ListBox2 et vice-versa.
Pour celà, ListBox2 est reliée à ListBox1 par l'inspecteur d'objets pour les 2 events qui suivent :

procedure TForm1.ListBox1DragOver(Sender, Source: TObject; X, Y: Integer;
  State: TDragState; var Accept: Boolean);
begin
  Accept := Source is TListBox;
end;

procedure TForm1.ListBox1DragDrop(Sender, Source: TObject; X, Y: Integer);
var
  i: Integer;
begin
  // ordre inversé
  {
  for i := TListBox(Source).Items.Count - 1 downto 0 do
  begin
    if TListBox(Source).Selected[i] then
    begin
      TListBox(Sender).Items.Add(TListBox(Source).Items[i]);
      TListBox(Source).Items.Delete(i);
    end;
  end;
  }
  // ou si on veut respecter l'ordre des items :
  for i := 0 to TListBox(Source).Items.Count - 1 do
    if TListBox(Source).Selected[i] then
      TListBox(Sender).Items.Add(TListBox(Source).Items[i]);
  for i := TListBox(Source).Items.Count - 1 downto 0 do
    if TListBox(Source).Selected[i] then
      TListBox(Source).Items.Delete(i);
end;

Bonnes fêtes de fin d'année.
Messages postés
991
Date d'inscription
samedi 25 octobre 2003
Statut
Membre
Dernière intervention
29 août 2013
5
dans l'evenement OnDragGrop, tu as la source, tu peux la caster en  listbox et attaquer la propriete de selection
Messages postés
67
Date d'inscription
mercredi 30 juin 2004
Statut
Membre
Dernière intervention
6 octobre 2011
4
Bonsoir,
merci beaucoup, la deuxieme solution etant bien sûr beaucoup plus elegante.
mais les deux fonctionnent.

Bonnes fêtes de fin d'année et encore merci.

petit a petit je progresse. Mais j'ai vraiement beaucoup de subtilités a comprendre encore!!!

A+

morinxav
Messages postés
2527
Date d'inscription
jeudi 15 janvier 2004
Statut
Membre
Dernière intervention
16 octobre 2019
14
« merci beaucoup, la deuxieme solution etant bien sûr beaucoup plus elegante. »

'faut pas exagérer!
L'élégance a aussi son revers de médaille... 
Messages postés
1721
Date d'inscription
vendredi 27 décembre 2002
Statut
Modérateur
Dernière intervention
30 août 2020
3
Bah, les 2 approches sont légèrement différentes, c'est tout.
Pour l'élégance, faudrait demander à Mme de Fontenay...
Messages postés
67
Date d'inscription
mercredi 30 juin 2004
Statut
Membre
Dernière intervention
6 octobre 2011
4
Bon ok je suis daccord,


Dernier petit detail, avec vos 2 solutions je deplace ma selection certe mais a la fin de la listbox et non ou je veux...


je croyais pouvoir adapter l'une ou l'autre des solutions mais a priori je suis vraiement trop mauvais!


Auriez vous une solution?


Merci d'avance


A+
morinxav
Messages postés
2527
Date d'inscription
jeudi 15 janvier 2004
Statut
Membre
Dernière intervention
16 octobre 2019
14
Demande au dandy !
Messages postés
1721
Date d'inscription
vendredi 27 décembre 2002
Statut
Modérateur
Dernière intervention
30 août 2020
3
Ok...

procedure TForm1.ListBox1DragDrop(Sender, Source: TObject; X, Y: Integer);
var
  i: Integer;
  CursorPos: TPoint;
  Index: Integer;
begin
  CursorPos := Point(X, Y);   // position du curseur
  Index := ListBox1.ItemAtPos(CursorPos, True);
  for i := TListBox(Source).Items.Count - 1 downto 0 do
  begin
    if TListBox(Source).Selected[i] then
    begin
      TListBox(Sender).Items.Insert(Index, TListBox(Source).Items[i]);
      TListBox(Source).Items.Delete(i);
    end;
  end;
end;

En rose, je trouve que c'est plus raffiné
Messages postés
1721
Date d'inscription
vendredi 27 décembre 2002
Statut
Modérateur
Dernière intervention
30 août 2020
3
Hé, morinxav2, arrête d'agacer cari, s'il te plaît.
Tu me le rends tout grognon.

Et puis dis donc, le côté "je suis vraiment trop mauvais", ça serait pas une manière de nous faire bosser à ta place ?
Messages postés
1721
Date d'inscription
vendredi 27 décembre 2002
Statut
Modérateur
Dernière intervention
30 août 2020
3
Petite correction, sinon ça plante quand la ListBox destinataire est vide :

procedure TForm1.ListBox1DragDrop(Sender, Source: TObject; X, Y: Integer);
var
  i: Integer;
  CursorPos: TPoint;
  Index: Integer;
begin
  CursorPos := Point(X, Y);
  Index := ListBox1.ItemAtPos(CursorPos, True);
  for i := TListBox(Source).Items.Count - 1 downto 0 do
  begin
    if TListBox(Source).Selected[i] then
    begin
      if Index < TListBox(Sender).Items.Count then
        TListBox(Sender).Items.Insert(Index, TListBox(Source).Items[i])
      else
        TListBox(Sender).Items.Add(TListBox(Source).Items[i]);
      TListBox(Source).Items.Delete(i);
    end;
  end;
end;

En violet, c'est assez classe aussi...
Messages postés
2527
Date d'inscription
jeudi 15 janvier 2004
Statut
Membre
Dernière intervention
16 octobre 2019
14
Moi, j'préfère le bleu...
C'est moins classe, mais ça fait pro. 
Messages postés
1721
Date d'inscription
vendredi 27 décembre 2002
Statut
Modérateur
Dernière intervention
30 août 2020
3
J'ai fait une erreur grossière dans mon code précédent, il fallait faire :

procedure TForm1.ListBox1DragDrop(Sender, Source: TObject; X, Y: Integer);
var
  i: Integer;
  CursorPos: TPoint;
  Index: Integer;
begin
  CursorPos := Point(X, Y);
  Index := TListBox(Sender).ItemAtPos(CursorPos, True);
  for i := TListBox(Source).Items.Count - 1 downto 0 do
  begin
    if TListBox(Source).Selected[i] then
    begin
      if Index < -1 then
        TListBox(Sender).Items.Insert(Index, TListBox(Source).Items[i])
      else
        TListBox(Sender).Items.Add(TListBox(Source).Items[i]);
      TListBox(Source).Items.Delete(i);
    end;
  end;
end;

Mais quoi qu'il en soit, j'ai continué à travailler ce code quand même un peu bancal.
Je passe finalement par une StringList pour garder l'ordre dans lequel ont été trouvés les items de la LisBox source... (+ 1 pour Cari )
Je vais poster la source que je suis en train de finaliser, elle pourra servir à d'autres.

Bonne prog' dominicale

P-S: code en bleu pour faire plus pro
Messages postés
67
Date d'inscription
mercredi 30 juin 2004
Statut
Membre
Dernière intervention
6 octobre 2011
4
Bonsoir,


Je suis au moins heureux de 3 choses;
   -Vous m'avez trouvez la solution, et que vous le croyez ou non j'avais dèja passer du temps dessus. J'avais pensé au items.move et j'avais pas vue le items.insert.
   -D'avoir déclenché tant d'angouement sur la resolution de mon problème.
   -D'avoir declenché l'envie a Japee de faire une demo, pour que tout le monde en profite.
Je remercie et m'excuse auprès de  Japee et Caribensila de s'être couché, je pense plus tard que moi (2H du mat pour ma part), mais le lendemain j'ai mes trois gamains qui galopent (8 ans, 3ans, 3mois).

et encore merci à qui m'a permis de debuter la programmation en 2004.

Deux dernières petites questions pour la route; 
   - Qu'elle est l'avenir du pascal et de delphi? 
   - Qu'elle langage est le plus utilisé en ce moment?
   - Que faut- il pour programmer pour Linux? (Je ne passerais pas sous Vista, Ras le bol de Bill Gates!!!!)
A+

morinxav