即使设置了GridView.DataKeyNames,Gridview.DataKeys []仍为空

时间:2009-03-10 23:24:52

标签: .net asp.net

GridView.DataKeynames存储GridView控件中显示的项的主键字段的名称。

1)即使我设置了DataKeyNames,GridView仍然不会在DataKey对象中存储记录的主键值:


protected void SqlDataSource1_Selected(object sender, 
          SqlDataSourceStatusEventArgs e)
{
      Label2.Text = GridView2.DataKeys[0].Value.ToString();//exception
}

为什么不呢?

2)我假设当设置DataKeyNames时,DataKey对象存储主键的原始值和新值(假设我们发出了更新命令),当更新完成时,DataKey对象会丢弃原始值吗? / p>

谢谢

4 个答案:

答案 0 :(得分:4)

我想这太迟了......但首先,你试图在数据检索之后立即获取数据密钥,而不是在数据绑定之后。 DataBeys直到DataBind才会填充。

其次,数据键不存储新的更新后值。它们是绑定期间可用的内容的副本,存储在视图状态中,主要用于在回发后定位记录而不进行另一次绑定。

答案 1 :(得分:1)

我在一个aspView中的GridView遇到了这个问题:PlaceHolder在加载页面时被设置为Visible = false。 OnLoad for!IsPostBack中的整个页面发生了数据绑定。单击按钮时,PlaceHolder将设置为Visible = true。所有数据都会显示,但GridView上的DataKeys []始终为空。

当控件不可见时,似乎GridView ViewState无法正确保留。我的补救措施是在显示它之前将DataBind()放在GridView上。

答案 2 :(得分:0)

某种程度上相关的答案可能会帮助2年以上的人...(确切地说是2年零2天) 我有一个 EntityDataSource 绑定到 GridView ,我希望基于实体的Id(DataKey值)在gridview中隐藏选定的CommandButton,我在RowDataBound事件中做了但是我使用此代码获得了 indexOutOfBoundException (尽管DataKeys应该在RowDataBound中可用):

protected void GridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        int id = (Int32)GridView.DataKeys[e.Row.RowIndex].Value;//<==Here
        if (FilterList.Contains(id))
        {
            e.Row.Cells[3].Visible= false;
        }
    }          
}

解决方法是在网格视图标记中添加Id作为模板字段集(它可见!),然后检查单元格值而不是DataKeys中的id,如下所示:

if (e.Row.RowType == DataControlRowType.DataRow)
{

     TableCell cell =e.Row.Cells[0];
     Label s = (Label)cell.Controls[1];

     int id = Convert.ToInt32(s.Text);              
     if (FilterList.Contains(id))
     {
         //hide the Select CommandButton
         e.Row.Cells[3].Visible = false;
     }

     //Hide the id cell
     e.Row.Cells[0].Visible = false;
}

if (e.Row.RowType == DataControlRowType.Header)
{
    //Hide the Id header cell
    e.Row.Cells[0].Visible = false;
}

希望这有助于某人

答案 3 :(得分:0)

您也可以通过使用RowDataBound中的e.Row.DataItem来解决此问题,而无需在GridView中显示id字段,如下所示:

protected void GridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        DataRowView drv =  e.Row.DataItem as DataRowView // Cast to correct type
        if (drv != null)
        {
            int id = Convert.ToInt32(drv["Id"]);
            if (FilterList.Contains(id))
            {
                e.Row.Cells[3].Visible= false;
            }
        }
    }          
}

请注意,您需要将DataItem设置为DataBind用于GridView的正确类型。例如,如果将GridView数据绑定到DataGrid,则DataItem应该是DataRowView,如果您将数据绑定到CustomObject类型的对象数组,则可以将DataItem转换为CustomObject类型