Get current index from foreach loop
This question already has an answer here:
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;
}
You can't, because IEnumerable
doesn't have an index at all... if you are sure your enumerable has less than int.MaxValue
elements (or long.MaxValue
if you use a long
index), you can:
Don't use foreach, and use a for
loop, converting your IEnumerable
to a generic enumerable first:
var genericList = list.Cast<object>();
for(int i = 0; i < genericList.Count(); ++i)
{
var row = genericList.ElementAt(i);
/* .... */
}
Have an external index:
int i = 0;
foreach(var row in list)
{
/* .... */
++i;
}
Get the 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;
/* .... */
}
In your case, since your IEnumerable
is not a generic one, I'd rather use the foreach
with external index (second method)... otherwise, you may want to make the Cast<object>
outside your loop to convert it to an IEnumerable<object>
.
Your datatype is not clear from the question, but I'm assuming object
since it's an items source (it could be DataGridRow
)... you may want to check if it's directly convertible to a generic IEnumerable<object>
without having to call Cast<object>()
, but I'll make no such assumptions.
All this said:
The concept of an "index" is foreign to an IEnumerable
. An IEnumerable
can be potentially infinite. In your example, you are using the ItemsSource
of a DataGrid
, so more likely your IEnumerable
is just a list of objects (or DataRows
), with a finite (and hopefully less than int.MaxValue
) number of members, but IEnumerable
can represent anything that can be enumerated (and an enumeration can potentially never end).
Take this example:
public static IEnumerable InfiniteEnumerable()
{
var rnd = new Random();
while(true)
{
yield return rnd.Next();
}
}
So if you do:
foreach(var row in InfiniteEnumerable())
{
/* ... */
}
Your foreach
will be infinite: if you used an int
(or long
) index, you'll eventually overflow it (and unless you use an unchecked
context, it'll throw an exception if you keep adding to it: even if you used unchecked
, the index would be meaningless also... at some point -when it overflows- the index will be the same for two different values).
So, while the examples given work for a typical usage, I'd rather not use an index at all if you can avoid it.
使用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 ...
}
链接地址: http://www.djcxy.com/p/52966.html
上一篇: 在C#中获取Enumerator.Current的索引
下一篇: 从foreach循环获取当前索引