Utilisation de C # et Silverlight
Comment obtenir l'index de l'élément en cours dans la liste?
Code:
IEnumerable list = DataGridDetail.ItemsSource as IEnumerable;
List<string> lstFile = new List<string>();
foreach (var row in list)
{
bool IsChecked = (bool)((CheckBox)DataGridDetail.Columns[0].GetCellContent(row)).IsChecked;
if (IsChecked)
{
// Here I want to get the index or current row from the list
}
}
Comment y parvenir
IEnumerable list = DataGridDetail.ItemsSource as IEnumerable;
List<string> lstFile = new List<string>();
int i = 0;
foreach (var row in list)
{
bool IsChecked = (bool)((CheckBox)DataGridDetail.Columns[0].GetCellContent(row)).IsChecked;
if (IsChecked)
{
MessageBox.show(i);
--Here i want to get the index or current row from the list
}
++i;
}
Vous ne pouvez pas, car IEnumerable
n'a pas d'index du tout ... si vous êtes sûr que votre énumérable a moins de int.MaxValue
Éléments (ou long.MaxValue
si vous utilisez un index long
) , vous pouvez:
N'utilisez pas foreach et utilisez une boucle for
, convertissant d'abord votre IEnumerable
en un énumérable générique:
var genericList = list.Cast<object>();
for(int i = 0; i < genericList.Count(); ++i)
{
var row = genericList.ElementAt(i);
/* .... */
}
Avoir un index externe:
int i = 0;
foreach(var row in list)
{
/* .... */
++i;
}
Obtenez l'index via Linq:
foreach(var rowObject in list.Cast<object>().Select((r, i) => new {Row=r, Index=i}))
{
var row = rowObject.Row;
var i = rowObject.Index;
/* .... */
}
Dans votre cas, puisque votre IEnumerable
n'est pas générique, je préfère utiliser le foreach
avec un index externe (deuxième méthode) ... sinon, vous voudrez peut-être faire le Cast<object>
En dehors de votre boucle pour le convertir en IEnumerable<object>
.
Votre type de données n'est pas clair à la question, mais je suppose que object
puisqu'il s'agit d'une source d'éléments (il pourrait être DataGridRow
) ... vous voudrez peut-être vérifier s'il est directement convertible en un générique IEnumerable<object>
sans avoir à appeler Cast<object>()
, mais je ne ferai pas de telles hypothèses.
Le concept d'un "index" est étranger à un IEnumerable
. Un IEnumerable
peut être potentiellement infini. Dans votre exemple, vous utilisez le ItemsSource
d'un DataGrid
, donc plus probablement votre IEnumerable
n'est qu'une liste d'objets (ou DataRows
), avec un nombre fini (et, espérons-le, inférieur à int.MaxValue
) de membres, mais IEnumerable
peut représenter tout ce qui peut être énuméré (et une énumération peut potentiellement ne jamais se terminer).
Prenez cet exemple:
public static IEnumerable InfiniteEnumerable()
{
var rnd = new Random();
while(true)
{
yield return rnd.Next();
}
}
Donc si vous le faites:
foreach(var row in InfiniteEnumerable())
{
/* ... */
}
Votre foreach
sera infini: si vous avez utilisé un index int
(ou long
), vous finirez par le déborder (et à moins d'utiliser un unchecked
contexte, il lèvera une exception si vous continuez à y ajouter: même si vous avez utilisé unchecked
, l'index serait également vide de sens ... à un moment donné -quand il débordera- l'index sera le même pour deux valeurs différentes).
Ainsi, alors que les exemples donnés fonctionnent pour une utilisation typique, je préfère ne pas utiliser du tout d'index si vous pouvez l'éviter.
list = list.Cast<object>().Select( (v, i) => new {Value= v, Index = i});
foreach(var row in list)
{
bool IsChecked = (bool)((CheckBox)DataGridDetail.Columns[0].GetCellContent(row.Value)).IsChecked;
row.Index ...
}
Vous avez deux options ici, 1. Utilisez for
à la place pour foreach
pour l'itération. Mais dans votre cas, la collection est IEnumerable et la limite supérieure de la collection est inconnue, donc foreach sera la meilleure option . donc je préfère utiliser une autre variable entière pour tenir le nombre d'itérations: voici le code pour ça:
int i = 0; // for index
foreach (var row in list)
{
bool IsChecked;// assign value to this variable
if (IsChecked)
{
// use i value here
}
i++; // will increment i in each iteration
}