2009-10-30 7 views
0

Dans mon application C#, j'ai deux contrôles ListBox. Un ListBox, nommé lstCategory, est rempli d'éléments récupérés à partir d'une base de données. L'autre ListBox est nommé lstSelCategory. Je souhaite déplacer les éléments sélectionnés de lstCategory vers lstSelCategory, puis trier les éléments dans lstSelCategory. Comment pourrais-je faire cela efficacement? Toute aide serait appréciée.Déplacer des éléments de liste d'une liste à une autre

protected void BtnCopyNext_Click(object sender, EventArgs e) 
{ 

    try 
    { 
     MakeDecision(lstCategory,lstSelCategory); 
    } 
    catch (Exception ex) 
    { 

    } 


} 
private void MakeDecision(ListBox Source, ListBox Target) 
{ 
    int[] selectedIndices; 
    try 
    { 
     selectedIndices = Source.GetSelectedIndices(); 
     if (!(selectedIndices.Length == 0)) 
     { 
      Copy(Source, Target); 
     } 

    } 
    catch (Exception ex) 
    { 
     throw ex; 
    } 
} 
private void Copy(ListBox Source, ListBox Target) 
{ 
    int[] selectedIndices; 
    ListItemCollection licCollection; 
    ListBox objTarget; 
    try 
    { 
     selectedIndices = Source.GetSelectedIndices(); 
     licCollection = new ListItemCollection(); 
     objTarget = new ListBox(); 
     if (Target != null && Target.Items.Count > 0) 
     { 
      foreach (ListItem item in Target.Items) 
      { 
       objTarget.Items.Add(item); 
      } 
      Target.Items.Clear(); 
     } 
     int selectedIndexLength = selectedIndices.Length; 
     for (int intCount = 0; intCount < selectedIndexLength; intCount++) 
     { 
      licCollection.Add(Source.Items[selectedIndices[intCount]]); 
     } 
     int collectionCount = licCollection.Count; 
     for (int intCount = 0; intCount < collectionCount; intCount++) 
     { 
      Source.Items.Remove(licCollection[intCount]); 
      if (!objTarget.Items.Contains(licCollection[intCount])) 
       objTarget.Items.Add(licCollection[intCount]); 
     } 
     Target.DataSource = ConvertToArrayList(objTarget); 
     Target.DataBind(); 
    } 
    catch (Exception ex) 
    { 
     throw ex; 
    } 
    finally 
    { 
     licCollection = null; 
     objTarget = null; 
    } 
} 
private ArrayList ConvertToArrayList(ListBox Source) 
{ 
    ArrayList arrayList; 
    try 
    { 
     arrayList = new ArrayList(); 
     foreach (ListItem item in Source.Items) 
      arrayList.Add(item.Text); 
     arrayList.Sort(); 
    } 
    catch (Exception ex) 
    { 
     throw ex; 
    } 
    return arrayList; 
} 
+0

S'il vous plaît poster votre code - nous ne pouvons pas aider à diagnostiquer ce qui ne va pas jusqu'à ce que nous voyons votre code. –

Répondre

0

Pourquoi pas juste?

var r = (from p in lstCategory.SelectedItems.Cast<string>() 
    where p.Length > 0 
    orderby p 
    select p); 

lstSelcategory.Items.AddRange(r.ToArray()); 
+0

Cela ne fonctionnera pas dans les versions de .net avant 3.5 bien sûr. –

0

On dirait qu'il y a beaucoup de travail inutile ici.

Y a-t-il une raison particulière pour laquelle vous convertissez les articles de ListBox en ArrayList? Ses éléments implémentent déjà IEnumerable, et devraient fonctionner comme le DataSource.

En outre, pourquoi databind? Vous déplacez déjà des éléments d'une zone de liste à une autre via la méthode Add. À moins qu'il y ait quelque chose que je ne vois pas ici, l'opération de liaison de données est coûteuse et complètement inutile.

MISE À JOUR Vous avez demandé code collé, donc je vais coller une partie de votre code et en discuter:

private void Copy(ListBox Source, ListBox Target) { 
    int[] selectedIndices; 
    ListItemCollection licCollection; 
    ListBox objTarget; 
    try 
    { 
     selectedIndices = Source.GetSelectedIndices(); 
     licCollection = new ListItemCollection(); 
     objTarget = new ListBox(); 
     if (Target != null && Target.Items.Count > 0) 
     { 
      foreach (ListItem item in Target.Items) 
      { 
       objTarget.Items.Add(item); 
      } 
      Target.Items.Clear(); 
     } 
     int selectedIndexLength = selectedIndices.Length; 
     for (int intCount = 0; intCount < selectedIndexLength; intCount++) 
     { 
      licCollection.Add(Source.Items[selectedIndices[intCount]]); 
     } 
     int collectionCount = licCollection.Count; 
     for (int intCount = 0; intCount < collectionCount; intCount++) 
     { 
      Source.Items.Remove(licCollection[intCount]); 
      if (!objTarget.Items.Contains(licCollection[intCount])) 
       objTarget.Items.Add(licCollection[intCount]); 
     } 

Jusqu'à ce point, vous avez fait tout à peu près vous avez besoin faire. Les éléments ont déjà été ajoutés aux contrôles ListBox. Lorsque la page est rendue, le Framework va parcourir la collection ListItem et afficher le code HTML approprié pour les éléments. Si ViewState est activé pour le contrôle, les éléments auront ViewState mis en cache pour eux.

Mais alors, vous passez à faire:

  Target.DataSource = ConvertToArrayList(objTarget); 
     Target.DataBind(); 

    } 
    catch (Exception ex) 
    { 
     throw ex; 
    } 
    finally 
    { 
     licCollection = null; 
     objTarget = null; 
    } 
} 

Maintenant, ma compréhension de liaison de données me dit que cette série de déclarations complètement écrase tout ce que vous avez enregistré dans le ListItemCollection. Donc, tout ce travail que vous avez fait dans les étapes ci-dessus est oblitéré.

De plus, vous effectuez un appel à une fonction, ConvertToArrayList:

private ArrayList ConvertToArrayList(ListBox Source) { 
    ArrayList arrayList; 
    try  { 
     arrayList = new ArrayList(); 
     foreach (ListItem item in Source.Items) 
      arrayList.Add(item.Text); 
     arrayList.Sort(); 
    } 
    catch (Exception ex) 
    { 
     throw ex; 
    } 
    return arrayList; 
} 

Maintenant, tout cela est bon et bien, mais le problème est le suivant: vous pouvez simplement définir la ListItemCollection être votre source de données. Ou, comme nous l'avons montré, vous pouvez éviter complètement la liaison de données, puisque vous êtes déjà en train de créer les listes vous-même et que vous laissez tomber cet appel de fonction.

Il semble que vous deviez décider si vous souhaitez créer la liste vous-même ou lier les données. Si vous voulez lier les données, nettoyez comment vous le faites. Si vous ne voulez pas lier les données, débarrassez-vous de tout code qui n'est pas absolument nécessaire pour construire la liste et la gérer.

AUSSI:

  • Vous êtes attraper une exception (de type Exception, pas moins) et ne rien faire avec elle, mais il rethrowing. Si vous n'avez pas l'intention de faire quoi que ce soit avec cette exception, supprimez la clause Catch. Si vous prévoyez de réémettre l'exception, le jeter comme celui-ci pour conserver la trace de la pile:

    try 
    { 
        // Blahdy blahdy 
    } catch (Exception e) 
    { 
        throw; // Do not pass e; this preserves the stack trace. 
    } 
    
  • Configuration manuelle des objets à null dans la clause Finally est une mise en réserve des langues anciennes qui n'avait pas automatique collecte des ordures. J'éliminerais ce code car il encombre le corps de la fonction et rend la lecture plus difficile. Étant donné les deux points ci-dessus, il semble que vous pouvez supprimer l'intégralité de Try...Catch...Finally, et laisser les exceptions monter en bulle dans la chaîne alimentaire.

+0

Veuillez coller le code. – Sakthivel

Questions connexes