为什么中继器返回DataRowView而不是DataRow?

3
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;
}

出现异常,提示“无法将类型为'System.Data.DataRowView'的对象强制转换为类型'System.Data.DataRow'。”

DataRow是DataTable的一个元素,但为什么e.Item.DataItem会变成DataRowView?

有人能找到提到这一点的MSDN文档吗?


我不确定这个东西为什么会做它所做的事情,可能是因为重复器产生了 DataRowView 对象。显然,使用 var row = ((DataRowView)e.Item.DataItem).Row; 可以解决这个问题。 - Sergey Kalinichenko
不确定为什么会得到 DataRowView - 它是 DataRow 的自定义版本,但您可以像这样将其用作 DataRow - https://stackoverflow.com/questions/17089147/a-way-to-get-a-datarow-from-a-datarowview - Ziv Weissman
3个回答

4
这种行为由 DataTable 类定义。与典型的集合类不同,DataTable 实现 IListSource 而不是 IEnumerable。IListSource 接口允许类 "自定义" 提供给数据绑定控件(如 Repeater)的数据。 DataTable 的 IListSource 实现 返回 DefaultView,因此
repeater.DataSource = dt;

实际上等同于

repeater.DataSource = dt.DefaultView;

DefaultView的类型是DataView,它是一个DataRowView集合。这就是为什么您的数据项是DataRowView对象的原因。

2

DataRowView封装了DataRow,增加了在Web控件(如Repeaters)上下文中有用的绑定功能。

如果您想与底层行交互,只需使用Row属性,像这样:

var row = e.Item.DataItem.Row;

这可能是一个重复的问题,与C#中如何将DataRowView转换为DataRow有关。请参考此链接

我不是在问“如何”,而是在问“为什么”。 - Gqqnbig

0
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;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接