Prob echange "total" entre 2 listbox

Résolu
coucoual Messages postés 37 Date d'inscription lundi 1 mars 2004 Statut Membre Dernière intervention 5 septembre 2007 - 13 juil. 2007 à 11:55
ctx_man Messages postés 285 Date d'inscription mardi 28 décembre 2004 Statut Membre Dernière intervention 20 janvier 2013 - 17 juil. 2007 à 15:36
Bonjour
Voila j'ai un soucis sur un petit bout de code entre un echange total entre deux listbox. En effet, l echange fonctionne mais juste 1 sur 2. Je pense que c'est une toute petite erreur de logique et donc un oeil avertit trouvera de suite la faute :)

public void EchangeTout(ListBox lstSource, ListBox lstDestination)
{
//Ajoute tous les elements de la liste Source vers la liste Destination

int lgTmp = 0;

for(lgTmp = 1; (lgTmp <=lstSource.Items.Count); lgTmp++)
{
lstSource.SelectedIndex = (lgTmp - 1);
//lstSource.SelectedItem = lgTmp;
lstDestination.Items.Add(lstSource.SelectedItem);
lstSource.Items.RemoveAt(lstSource.SelectedIndex);
}
}

Voila merci pour votre aide ... dans ma logique cela doit fonctionner mais je n'ai pas l'habitude de manipuler cela ;)
++

9 réponses

ctx_man Messages postés 285 Date d'inscription mardi 28 décembre 2004 Statut Membre Dernière intervention 20 janvier 2013 3
13 juil. 2007 à 12:19
Salut !
Tu parle d'échange, mais ton code semble vider la liste source dans la liste destination.

Ton problème de 1/2 vient de tes index.
A chaque tour de boucle, tu incrémente l'indexe, normal.
Sauf que à chaque tour de boucle, tu supprime également un élément.

Par conséquent, l'élément d'indexe 10 par exemple, devient l'élément d'index 9.
Si tu change le nombre d'élément d'une liste pendant que tu la parcourt, les indexes deviennent faux.

Solution :
1) Parcour ta liste
for(int lgTmp 0; lgTmp < lstSource.Items.Count; lgTmp++) //On début à 0, et strictement inférieur à Count (Si Count 12, les indexes sont [0][1]...[11])
{
lstDestination.Items.Add(lstSource.Items[lgTmp]); //Item est un tableau, pas la peine de sélectionner un élément pour l'obtenir.
}

2) Vide ta liste :
lstSource.Items.Clear();

C'est tout.
Bonne continuation.
3
ctx_man Messages postés 285 Date d'inscription mardi 28 décembre 2004 Statut Membre Dernière intervention 20 janvier 2013 3
13 juil. 2007 à 18:30
Honnetement, je comprend pas ce que tu veux faire avec ce code. Pourquoi tu fait du récursif ?



Tu souhaite que l'élément sélectionné dans la liste source soit transféré dans la liste cible quand tu clique sur un bouton ?

Dans ce cas le code à éxécuté se fait sur fait sur l'évènement du clique sur le bouton (double clique sur ton bouton dans l'editeur de WindowForm).


ca devrait t'enmener dans une fonction semblable à celle-ci :


private void Button1_click(object sender, EventArgs e)

{

}


Ensuite, pour envoyer un élément d'une liste à l'autre :

lstDestination.Items.add(lstSource.Items[lstSource.SelectedIndex]);

lstSource.Items.RemoveAt(lstSource.SelectedIndex);

lstSource.Update();

lstDestination.Update();


Pour transferer plusieurs éléments (multiselection)

for(int i; i < lstSource.SelectedIndices; i++)

lstDestination.Items.add(lstSource.Items[lstSource.SelectedIndices[i]]);

//Maintenant que tu as transferer les éléments sélectionnés, il faut les supprimés. Pour ca assure toi que le tableau lstSource.SelectedIndices est trié.

lstSource.SelectedIndices.Sort();

//Puis parcours le tableau en partant de la fin, ainsi, les éléments supprimés n'influeront pas sur les indexes des éléments restant puisqu'ils possèdent un indice inférieur.

for(int i = lstSource.SelectedIndices.Count; i >= 0; i--)

lstSource.Items.RemoveAt(lstSource.SelectedIndices[i]);


Voilà, normalement ca devrait être bon, mais au moment où j'écrit ces lignes j'ai pas mon VS pour tester alors il y a surement des erreures. Mais ca doit pas être loin d'être bon, a toi de chercher. Bonne continuation.


Le travail c'est la santé, ne rien faire c'est la préservé !!!
3
ctx_man Messages postés 285 Date d'inscription mardi 28 décembre 2004 Statut Membre Dernière intervention 20 janvier 2013 3
17 juil. 2007 à 11:40
Salut !
Tu as de la chance, aujourd'hui je travail, j'ai donc mon VS à dispo. Je regarde ca et je te tient au courant.
3
ctx_man Messages postés 285 Date d'inscription mardi 28 décembre 2004 Statut Membre Dernière intervention 20 janvier 2013 3
17 juil. 2007 à 12:03
Bon alors voilà les codes que j'ai tester et qui fonctionnent chez moi :
Sélection simple :
if (lstSource.SelectedIndex != -1)
{
lstDestination.Items.Add(lstSource.SelectedItem);
lstSource.Items.Remove(lstSource.SelectedItem);
}

Sélection multiple :
while(lstSource.SelectedItems.Count > 0)
{
lstDestination.Items.Add(lstSource.SelectedItems[0]);
lstSource.Items.Remove(lstSource.SelectedItems[0]);
}

En travaillant avec SelectedItem(s) tu accède directements au objets, donc plus besoin de bidouiller pour que les indices correspondent.
Dans la sélection multiple, l'utilisation d'un while permet de vider la liste des objets selectionnés plutot que de la parcourir d'ans un sens puis dans l'autre. Car quand tu supprime un élément sélectionné il est directement supprimer de la liste des SelectedItems.
3

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
ctx_man Messages postés 285 Date d'inscription mardi 28 décembre 2004 Statut Membre Dernière intervention 20 janvier 2013 3
17 juil. 2007 à 15:26
Salut !
Tu sais, je ne fait du C# que depuis 3 semaines environs. Et je n'aime pas :D (mais j'ai pas le choix, le language m'est imposé).

Deux/trois petits conseils.
- Regarde bien de quoi dispose chacun de tes objets (methodes, propriétés, events, ...)
- Essaye d'utiliser des nom qui veulent dire quelque chose (parce que lst1, lst2, .... ca parle a personne et si tu lache ton code pendant plusieurs jours tu va ramer pour te le remettre en tête, surtout s'il grossit. Et puis c'est plus sympas pour tes éventuels collègues qui devront lire ton code)
- Essaye de faire quelque chose de plus efficace et plus clair. Pour ca impose toi des règles stricte de formattage. Si tu utilise 20 fois une propriété d'un objet, stock la plutot que l'invoquer à chaque fois (dans ce cas précis le problème est pas présent). Le framework est déjà d'une lenteur affligente, pas la peine de l'alourdir.
- Fait la manipulation à la main en décomposant le plus possible pour te donner une idée de comment faire en code.
- Pour t'éviter les type : System.Windows.Forms., insère un using en haut de ton code, comme je l'ai fait ci dessous.

using System.Windows.Forms;

public class Form2 : Form
{
private GroupBox groupBox1;
private GroupBox groupBox2;
private Button btnrefresh2;
private Button btnrefresh1;
private ListBox lst1;
private ListBox lst2;
private Button button1all;
private Button button2all;
private Button button1;
private Button button2;

private System.ComponentModel.Container components = null;

private void Form2_Load()
{
lst1.Items.Clear(); // Si ta form est créée à chaque fois, c'est une nouvelle form a chaque fois, donc c'est inutile, tes listes sont déjà vides.
lst2.Items.Clear(); // Idem

// Syntaxe trop lourde pour rien. Prend l'habitude de commencer à 0 et de faire des test en strictement supérieur/inférieur (de mannière générale c'est plus efficace)
// S'il n'y à qu'une ligne, les accolades sont superflues
// Par convention les indexs se nomment i, j, k, l, .....
// Si tu utilise x, y, z on pense naturellement à des coordonnées. Mais comme je dit, c'est une convention, pas une obligation absolue, si ca te chante de l'apeller SDfbjsfljnvgysdfDSFgivslkj c'est ton problème et celui de ceux qui liront ton code.
//for (int x = 1; x <= 10; x++)
//Voilà qui est plus clair non ?
for (int i = 0; i < 10; i++)
lst1.Items.Add("Piste " + i.ToString());
}

public Form2()
{
InitializeComponent();
Form2_Load(); //Perso je mettrai ton code de Form2_Load() directement ici. C'est peu courant les cas où on a besoin de l'évent OnLoad plusieur fois.
}

private void button1_Click(object sender, System.EventArgs e)
{
Echange(lst1, lst2);
}

private void button1all_Click(object sender, System.EventArgs e)
{
EchangeTout(lst1,lst2);
}

private void button2_Click(object sender, System.EventArgs e)
{
Echange(lst2, lst1);
}

private void button2all_Click(object sender, System.EventArgs e)
{
EchangeTout(lst2, lst1);
}

public void Echange(ListBox lstSource, ListBox lstDestination)
{
//Ici tu tu as mal comprit mon précédent post. Cette méthode est celle d'un échange simple
//Dans le cadre où un seul et unique élément est selectionnable (lstSource.SelectionMode = SelectionMode.one)
//Sélection simple :
if (lstSource.SelectedIndex != -1)
{
lstDestination.Items.Add(lstSource.SelectedItem);
lstSource.Items.Remove(lstSource.SelectedItem);
}
} //Elle se finit ici
//La suite c'est la méthode d'un échange simple également, mais dans le cadre où plusieurs éléments sont sélectionnables ((lstSource.SelectionMode = SelectionMode.multisimple ou Selection.multiextended)
//Il faut utiliser l'une ou l'autre, pas les deux en même temps. Je te conseil d'utiliser cette seconde methode car elle fonctionnera dans les deux cas puisque la selection simple n'est qu'un particulier de la selection multiple.
/*
//Sélection multiple :
while(lstSource.SelectedItems.Count > 0)
{
lstDestination.Items.Add(lstSource.SelectedItems[0]);
lstSource.Items.Remove(lstSource.SelectedItems[0]);
}
*/

public void EchangeTout(ListBox lstSource, ListBox lstDestination)
{
if(lstSource.Item != null) //On s'assure que ca ne va pas crasher
{
//Ici tu veux vider l'intégralité de la liste source dans la liste destination, nulle besoin de sélection
while(lstSource.Items.Count > 0)
lstDestination.Items.Add(lstSource.Items[0];
//Rien de plus.
}
}
}
3
ctx_man Messages postés 285 Date d'inscription mardi 28 décembre 2004 Statut Membre Dernière intervention 20 janvier 2013 3
17 juil. 2007 à 15:36
Ah oui, autre petite chose que j'ai oublier de "corriger" :
for (int i = 0; i < 10; i++)
lst1.Items.Add("Piste " + i.ToString());

C'est inutile de faire i.toString(). L'opérateur + est déjà surcharger pour convertir les types simples (non objets) en chaine de texte.
donc :
for (int i = 0; i < 10; i++)
lst1.Items.Add("Piste " + i);
3
coucoual Messages postés 37 Date d'inscription lundi 1 mars 2004 Statut Membre Dernière intervention 5 septembre 2007 1
13 juil. 2007 à 16:33
Merci effectivement maintenant ca marche mieu :)
Maintenant j'ai un pb dans mon echange principal de un item vers l'autre liste ...

public void Echange(ListBox lstSource, ListBox lstDestination)
{
//ajout d'un element de la liste Source vers la liste Destination
int lgTmp = 0;

if((lstSource.Items.Count > 0))
{
if((lstSource.SelectedIndex >= 0))
{
lgTmp = lstSource.SelectedIndex;
lstDestination.Items.Add(lstSource.Items[lgTmp]);
lstSource.Items.RemoveAt(lstSource.SelectedIndex);
}
}
lstSource.Focus();
if ((lstSource.Items.Count > lgTmp))
{
lstSource.SelectedIndex = lgTmp;
}
else if ((lstSource.Items.Count > 0))
{
lstSource.SelectedIndex = (lstSource.Items.Count - 1);
}
if ((lstSource.SelectedIndices.Count > 0))
{
for (lgTmp = 0; (lgTmp <= (lstSource.Items.Count - 1)); lgTmp++)
{
if(lstSource.SelectedItem.Equals(lgTmp))
{
lstSource.SelectedIndex = lgTmp;
break;
}
}
Echange(lstSource, lstDestination);
}
}

Voila si quelqu'un peut me dire pourquoi ca ne fait rien du tout alors que je voudrais que lorsque je selectionne un element et que j'appuye sur mon bouton qui execute cette fonction l'item passe sur l'autre listbox et s'efface de la principale.

Merci et bon WE :)
++
1
coucoual Messages postés 37 Date d'inscription lundi 1 mars 2004 Statut Membre Dernière intervention 5 septembre 2007 1
17 juil. 2007 à 10:10
Salut ! Merci bien pour ton aide :) j'ai essayer ca directement, corrigé les petits soucis comme tu n'avais pas ton Vs pour tester mais ca ne marche pas :(

Voila comment j'organise la chose :
private void button1_Click(object sender, System.EventArgs e)
{
Echange(lst1, lst2);
}

private void button1all_Click(object sender, System.EventArgs e)
{
EchangeTout(lst1,lst2);
}

private void button2_Click(object sender, System.EventArgs e)
{
Echange(lst2, lst1);
}

private void button2all_Click(object sender, System.EventArgs e)
{
EchangeTout(lst2, lst1);
}


public void Echange(ListBox lstSource, ListBox lstDestination)
{
lstDestination.Items.Add(lstSource.Items[lstSource.SelectedIndex]);
lstSource.Items.RemoveAt(lstSource.SelectedIndex);
lstSource.Update();
lstDestination.Update();

for(int i = 0; i < lstSource.SelectedIndices.Count; i++)
{
lstDestination.Items.Add(lstSource.Items[lstSource.SelectedIndices[i]]);
}

//lstSource.SelectedIndices.Sort();

for(int i = lstSource.SelectedIndices.Count; i >= 0; i--)
{
lstSource.Items.RemoveAt(lstSource.SelectedIndices[i]);
}

}

Et ma fonction echangetout sur laquelle tu m'avais aussi aidé ui elle marche parfaitement.
Mais la fonction echange, lorsque je selectionne un item et que je click sur l'echange simple, il ne se passe rien ...
J'ai cherché mais n'ai pas trouvé pourquoi il y avait un probleme :(

Merci
0
coucoual Messages postés 37 Date d'inscription lundi 1 mars 2004 Statut Membre Dernière intervention 5 septembre 2007 1
17 juil. 2007 à 14:06
Salut :)
Merci pour ton code c'est effectivement plus simple, quoique le premier doit marcher aussi normalement ... mais j'ai toujours un soucis chez moi qui ne doit pas etre relatif a l'exactitude du code mais surement a ma maniere de code (je suis en formation d'ingenieur aeronautique avec plutot de l'informatique embarquée ... et newbee en C#)
Donc pour mieux t'exposer ce que je souhaiterais faire j'ai pris quelques sreenshots :
La tete de mon projet :
http://www.casimages.com/img.php?i=070717020218869579.jpg

Et la partie avec les deux listbox :
http://www.casimages.com/img.php?i=070717020302869588.jpg

Donc voila en gros je souhaite cliquer sur un item, ensuite sur mon bouton et que ca passe dans la liste 2 et s'effacant de la liste 1 et inversement.

Je te mets la tout le code de ma form :

public class Form2 : System.Windows.Forms.Form
{
private System.Windows.Forms.GroupBox groupBox1;
private System.Windows.Forms.GroupBox groupBox2;
private System.Windows.Forms.Button btnrefresh2;
private System.Windows.Forms.Button btnrefresh1;
private System.Windows.Forms.ListBox lst1;
private System.Windows.Forms.ListBox lst2;
private System.Windows.Forms.Button button1all;
private System.Windows.Forms.Button button2all;
private System.Windows.Forms.Button button1;
private System.Windows.Forms.Button button2;

private System.ComponentModel.Container components = null;

private void Form2_Load()
{
lst1.Items.Clear();
lst2.Items.Clear();

for (int x = 1; x <= 10; x++)
{
lst1.Items.Add("Piste " + x.ToString());
}

}


public Form2()
{
//
// Requis pour la prise en charge du Concepteur Windows Forms
//
InitializeComponent();
Form2_Load();

//
// TODO : ajoutez le code du constructeur après l'appel à InitializeComponent
//
}



private void button1_Click(object sender, System.EventArgs e)
{
Echange(lst1, lst2);
}

private void button1all_Click(object sender, System.EventArgs e)
{
EchangeTout(lst1,lst2);
}

private void button2_Click(object sender, System.EventArgs e)
{
Echange(lst2, lst1);
}

private void button2all_Click(object sender, System.EventArgs e)
{
EchangeTout(lst2, lst1);
}

public void Echange(ListBox lstSource, ListBox lstDestination)
{
//Sélection simple :
if (lstSource.SelectedIndex != -1)
{
lstDestination.Items.Add(lstSource.SelectedItem);
lstSource.Items.Remove(lstSource.SelectedItem);
}

//Sélection multiple :
while(lstSource.SelectedItems.Count > 0)
{
lstDestination.Items.Add(lstSource.SelectedItems[0]);
lstSource.Items.Remove(lstSource.SelectedItems[0]);
}

/*
lstDestination.Items.Add(lstSource.Items[lstSource.SelectedIndex]);
lstSource.Items.RemoveAt(lstSource.SelectedIndex);
lstSource.Update();
lstDestination.Update();

for(int i = 0; i < lstSource.SelectedIndices.Count; i++)
{
lstDestination.Items.Add(lstSource.Items[lstSource.SelectedIndices[i]]);
}

//lstSource.SelectedIndices.Sort();

for(int i = lstSource.SelectedIndices.Count; i >= 0; i--)
{
lstSource.Items.RemoveAt(lstSource.SelectedIndices[i]);
}*/
}

public void EchangeTout(ListBox lstSource, ListBox lstDestination)
{
//Ajoute tous les elements de la liste Source vers la liste Destination
int lgTmp = 0;

for(lgTmp = 1; (lgTmp <=lstSource.Items.Count); lgTmp++)
{
lstSource.SelectedIndex = (lgTmp - 1);
lstDestination.Items.Add(lstSource.Items[lstSource.SelectedIndex]);
}

lstSource.Items.Clear();
}

}
}

Voila peut etre arriveras tu a voir ce qui ne va pas :(
En tout cas merci de ton aide et de ta disponibilité, je n'en esperais pas tant ;)
0
Rejoignez-nous