Reputation: 1764
In the following code, row
is considered as object
and not DataGridViewRow
.
foreach (var row in datagridview.Rows)
{
row.Visible = false //<- error because no Visible property
}
Am I missing something? shouldn't row be DataGridViewRow
?
Upvotes: 0
Views: 398
Reputation: 62488
DataGridView.Rows
is a collection which inherits from IEnumerable
not IEnumerable<T>
so you will need to use OfType<T>()
or Cast<T>()
to convert it to IEnumerable<T>
which are under System.Linq namespace, so you have to add using System.Linq
in your code file:
foreach (var row in datagridview.Rows.OfType<DataGridViewRow)
{
row.Visible = false //<- error because no Visible property
}
or you can cast it in foreach to DataGridViewRow
, if you dont want to use Cast<T>()
or OfType<T>()
:
foreach (DataGridView row in datagridview.Rows)
{
row.Visible = false //<- error because no Visible property
}
Upvotes: 2
Reputation: 13224
Your call to datagridview.Rows
returns an instance of type DataGridViewRowCollection
, which implements the non-generic ICollection
, IEnumerable
and IList
interfaces, thus, when you do "foreach" it will return instances of type System.Object
.
When using an implicitly typed variable with the var row
statement, the type of the row
variable will now become System.Object
.
To solve this, you can specify the type for row
explicitly in the foreach
statement:
foreach (DataGridViewRow row in datagridview.Rows)
{
row.Visible = false;
}
This works, because the foreach
implementation silently performs an explicit conversion (cast) of each object returned from the Enumerator.Current
to type DataGridViewRow
, as you can read about here.
Upvotes: 6
Reputation: 2283
You have to specifically set the type to DataGridViewRow. Here's why:
DataGridView.Rows
is of type DataGridViewSelectedRowCollection
. If we refractor that class, we get this:
public class DataGridViewSelectedRowCollection : BaseCollection, IList
The type is never specified, there are no generics used, just Plain old collections.
Therefore, .net cannot automatically infer a type. You have to specifically set the type to DataGridViewRow.
I'm guessing this is from the .Net days, when there were no generics.
Upvotes: 0
Reputation: 113242
DataGridViewRowCollection implements IEnumerable
but not IEnumerable<DataGridViewRow>
.
As such, it gives you a sequence of object
not of DataGridViewRow
.
Now the form:
foreach(DataGridViewRow row in datagridview.Rows)
{
row.Visible = false;
}
... will work, because foreach
involves in inherent cast.
This was a great convenience in the days of .NET1.0 and 1.1 when there were no generics and as such not generic enumerators. Today it's less useful than it was (especially as it means some things that will not work at runtime will still compile, that could be caught without this inherent cast), but it will work for you here.
var
though will always be of the type of the expression, which in this case is object
.
Upvotes: 0
Reputation: 533
try this;
for(var i =0;i< datagridview.Rows.Count;i++)
{ var row = datagridview.Rows[i];
row.Visible = false
}
Upvotes: 0