Why does repeater return DataRowView instead of DataRow?

Viewed 924
protected void Page_Load(object sender, System.EventArgs e)
{
    DataTable dt = GetDataTable("select * from AccountTypes");

    repeater.DataSource = dt;
    repeater.DataBind();
}

private void repeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
    if (e.Item.ItemType != ListItemType.Item) {
        return;
    }

    var row = (DataRow)e.Item.DataItem;
}

It throws exception that "Unable to cast object of type 'System.Data.DataRowView' to type 'System.Data.DataRow'."

DataRow is an element of DataTable, but why does e.Item.DataItem become DataRowView?

Can anyone find a MSDN documentation mentioning this?

3 Answers

This behavior is defined by the DataTable class. Unlike a typical collection class, DataTable implements IListSource instead of IEnumerable. The IListSource interface allows a class to "customize" the data provided to data-binding controls like Repeater.

DataTable's IListSource implementation returns DefaultView, so

repeater.DataSource = dt;

is actually equivalent to

repeater.DataSource = dt.DefaultView;

The type of DefaultView is DataView, which is a DataRowView collection. And that's why your data items are DataRowView objects.

DataRowView encapsulates a DataRow, adding binding functionality that is useful in the context of web controls (like Repeaters).

If you want to interact with the underlying Row, just use the Row property, like this:

var row = e.Item.DataItem.Row;

This is a possible duplicate of How can Convert DataRowView To DataRow in C#.

protected void Page_Load(object sender, System.EventArgs e)
{
    DataTable dt = GetDataTable("select * from AccountTypes");

    repeater.DataSource = dt;
    repeater.DataBind();
}

private void repeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
    if (e.Item.ItemType != ListItemType.Item) {
        return;
    }

    var row = e.Item.DataItem;
}
Related