You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何枚举ASP ListView控件?求助从控件还原为List的方法

解决ASP.NET ListView还原数据为List时DataItems为null的问题

我明白你遇到的困扰了——你已经成功把List转换成DataTable绑定到ListView,但想反向把ListView的数据还原成List时,发现DataItems集合是null,明明计数是对的却拿不到实际值,没法枚举所有行对吧?这其实是ASP.NET ListView的一个常见特性,我来给你拆解下原因和解决办法:

为什么DataItems会是null?

DataItems集合仅在数据绑定的过程中(比如调用DataBind()方法后的短时间窗口内)有效。当页面完成渲染、或者发生回发后,这个集合就会被清空变成null。而你需要的是遍历ListView实际渲染出来的控件项,也就是Items集合,它才是页面上真实存在的控件容器。

两种解决方案

方案一:直接复用原始数据源(最简单)

如果可以的话,在绑定ListView的时候,把原始的DataTable或者List存在ViewState里,之后要还原数据时直接从这里取,不用从控件里逐个提取值:

// 修改你的createLvwTable方法,把DataTable存到ViewState
private void createLvwTable(List<string> table)
{
    int index = 0;
    DataTable dt = new DataTable();
    foreach (string row in table)
    {
        string[] cells = row.Split('|');
        if (index == 0) // 处理表头列
        {
            for (int j = 0; j < cells.Length; j++)
            {
                dt.Columns.Add(cells[j]);
            }
        }
        else
        {
            DataRow dr = dt.NewRow();
            for (int j = 0; j < cells.Length; j++)
            {
                dr[j] = cells[j];
            }
            dt.Rows.Add(dr);
        }
        index++;
    }
    // 把DataTable存入ViewState,方便后续还原
    ViewState["ListViewSourceData"] = dt;
    lvwOutput.DataSource = dt;
    lvwOutput.DataBind();
}

// 还原成List<string>的方法
private List<string> RestoreListViewDataFromViewState()
{
    List<string> restoredList = new List<string>();
    if (ViewState["ListViewSourceData"] is DataTable dt)
    {
        // 先添加表头
        string header = string.Join("|", dt.Columns.Cast<DataColumn>().Select(col => col.ColumnName));
        restoredList.Add(header);
        
        // 遍历数据行,转换成|分隔的字符串
        foreach (DataRow row in dt.Rows)
        {
            string rowStr = string.Join("|", row.ItemArray);
            restoredList.Add(rowStr);
        }
    }
    return restoredList;
}

方案二:从ListView的Items集合提取数据

如果没办法保存原始数据源,那就直接遍历Items集合,从每个数据项的控件里提取值。这里需要注意你ListView的ItemTemplate结构,比如如果是用Table布局,或者用Label等控件显示数据:

private List<string> RestoreListViewDataFromItems()
{
    List<string> restoredList = new List<string>();
    
    // 先提取表头(如果ListView有HeaderTemplate的话)
    if (lvwOutput.HeaderRow != null)
    {
        List<string> headerCells = new List<string>();
        foreach (TableCell cell in lvwOutput.HeaderRow.Cells)
        {
            headerCells.Add(cell.Text.Trim());
        }
        restoredList.Add(string.Join("|", headerCells));
    }
    
    // 遍历所有数据项
    foreach (ListViewItem item in lvwOutput.Items)
    {
        if (item.ItemType == ListViewItemType.DataItem)
        {
            List<string> rowCells = new List<string>();
            
            // 情况1:如果是Table布局的ListView,直接遍历单元格
            var tableRow = item.Controls.OfType<Table>().FirstOrDefault()?.Rows[0];
            if (tableRow != null)
            {
                foreach (TableCell cell in tableRow.Cells)
                {
                    rowCells.Add(cell.Text.Trim());
                }
            }
            
            // 情况2:如果是用Label等控件绑定数据,通过FindControl获取
            // 比如你的ItemTemplate里有多个Label,ID分别是lblCol1、lblCol2...
            // rowCells.Add(((Label)item.FindControl("lblCol1")).Text.Trim());
            // rowCells.Add(((Label)item.FindControl("lblCol2")).Text.Trim());
            
            restoredList.Add(string.Join("|", rowCells));
        }
    }
    return restoredList;
}

注意事项

  • 确保ListView的ViewStateMode设置为Enabled(默认是开启的),否则回发时Items集合也会是空的。
  • 如果你的ListView是动态生成的模板,调用FindControl时要注意控件的层级结构,可能需要递归查找。

你提供的原始绑定代码:

private void createLvwTable(List<string> table) { 
    int index = 0; 
    DataTable dt = new DataTable(); 
    foreach (string row in table) { 
        string[] cells = row.Split('|'); 
        if (index == 0) // header column { 
            for (int j = 0; j < cells.Length; j++) { 
                dt.Columns.Add(cells[j]); //dt.Rows.Add(); 
            } 
        } else { 
            DataRow dr = dt.NewRow(); 
            for (int j = 0; j < cells.Length; j++) { 
                dr[j] = cells[j]; 
            } 
            dt.Rows.Add(dr); 
        } 
        index++; 
    } 
    lvwOutput.DataSource = dt; 
    lvwOutput.DataBind(); 
}

内容的提问来源于stack exchange,提问作者Bbb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:30:39