C#とSilverlightの使用
リスト内の現在のアイテムのインデックスを取得するにはどうすればよいですか?
コード:
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
}
}
これを達成する方法
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;
}
IEnumerable
にはインデックスがまったくないため、できません... enumerableが_int.MaxValue
_要素より少ないことが確実な場合(またはlong
インデックスを使用する場合は_long.MaxValue
_)、次のことができます。
Foreachを使用せず、for
ループを使用して、最初にIEnumerable
を汎用の列挙可能なものに変換します。
_var genericList = list.Cast<object>();
for(int i = 0; i < genericList.Count(); ++i)
{
var row = genericList.ElementAt(i);
/* .... */
}
_
外部インデックスがあります:
_int i = 0;
foreach(var row in list)
{
/* .... */
++i;
}
_
Linqを介してインデックスを取得します。
_foreach(var rowObject in list.Cast<object>().Select((r, i) => new {Row=r, Index=i}))
{
var row = rowObject.Row;
var i = rowObject.Index;
/* .... */
}
_
あなたの場合、あなたのIEnumerable
は一般的なものではないので、私はむしろforeach
を外部インデックスとともに使用します(2番目の方法)...そうでない場合は、_Cast<object>
_ループ外で_IEnumerable<object>
_に変換します。
あなたのデータタイプは質問から明確ではありませんが、アイテムソースであるためobject
であると仮定しています(DataGridRow
である可能性があります)... Cast<object>()
を呼び出さずに汎用_IEnumerable<object>
_を使用しますが、このような仮定は行いません。
「インデックス」の概念は、IEnumerable
とは無関係です。 IEnumerable
は潜在的に無限である可能性があります。あなたの例では、ItemsSource
のDataGrid
を使用しているため、IEnumerable
は単なるオブジェクトのリスト(またはDataRows
)であり、メンバーの数は有限(そして願わくば_int.MaxValue
_未満)ですが、IEnumerable
は列挙可能なものを表すことができます(そして列挙は潜在的に終わることはありません)。
次の例をご覧ください。
_public static IEnumerable InfiniteEnumerable()
{
var rnd = new Random();
while(true)
{
yield return rnd.Next();
}
}
_
その場合:
_foreach(var row in InfiniteEnumerable())
{
/* ... */
}
_
foreach
は無限になります。int
(またはlong
)インデックスを使用した場合、最終的にオーバーフローします(unchecked
を使用しない限り)コンテキスト、追加し続けると例外がスローされます:unchecked
を使用した場合でも、インデックスは無意味になります...ある時点で-オーバーフローすると-インデックスは同じになります2つの異なる値)。
したがって、与えられた例は典型的な使用法で機能しますが、それを避けることができるなら、私はむしろインデックスをまったく使用したくないです。
使用 Enumerable.Select <TSource、TResult>メソッド(IEnumerable <TSource>、Func <TSource、Int32、TResult>)
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 ...
}
ここには2つのオプションがあります。1。繰り返しのfor
の代わりにforeach
を使用します。ただし、コレクションはIEnumerableであり、コレクションの上限は不明なので、foreachが最適なオプションです。だから私は別の整数変数を使用して反復カウントを保持することを好みます:そのためのコードは次のとおりです:
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
}