我有一组带有一组固定(写入ASPX标记)列的GridView。在此列集合的末尾,在页面加载期间,我添加了另外几列(列数根据我相对于网格实体存储的键值对的数量而有所不同)并且我设置了控件的ID我动态添加,与密钥相关:
//Dictionary<string, string> myDictionary ...
foreach (string in myDictionary.Keys)
{
var tf = new TemplateField();
tf.HeaderText = k;
tf.ItemTemplate = new Label("key_" + k);
gridview.Columns.Add(tf);
}
在RowDataBound事件期间,我查看键值对,调用e.Row.FindControl
以查找应具有此值的标签,并填充值:
foreach (var k in myDictionary.Keys)
{
Label lb = (Label)e.Row.FindControl("key_" + k);
lb.Text = myDictionary[k];
}
这适用于初始显示,但在回发时,页面加载代码再次运行。此时,gridview似乎已经重新设置了我所创建的所有动态列,但它没有将任何数据放入其中。如果我将我的列包装在if(!IsPostback)
中添加代码以防止它们在回发时再次添加..那么我会看到我最初添加的列,但它们是空白的。如果我不使用IsPostback
检查,那么我将在呈现的页面中看到一组重复的列:一个空白,另一个包含值。空白列中的控件似乎不再具有相同的ID,因此当我的RowDataBound触发时,e.Row.FindControl("key_" + k)
返回null。当然,如果我不检查回发,只是再次添加列,新添加的列集将具有正确命名的ID的控件,它们将被填充..
为了对抗不断增长的空白列集,我计划删除(在页面加载中)我动态添加的任何已经使用错误的单元格控件ID重新设置的列,并再次添加它们。我可以通过向后循环列集合来执行此操作,直到我找到一个肯定是ASPX标记中存在的最后一列的列,但我唯一可以看到标识该列的标题是分配的标题文本标记(因为它没有自己的ID)。这是标记,例如:
这感觉就像是一种糟糕的做事方式:
for(int i = gv.Columns.Count-1; gv.Columns[i].HeaderText != "Edit Profile"; i--)
gv.Columns.RemoveAt(i); //remove all columns after the 'Edit Profile' one
..尤其是因为如果标题文本发生更改,或者键值对列表中包含“编辑配置文件”作为键,则会发生错误...
但是,我怎样才能更好地确定gridview中的哪一列是因为它是在标记中添加的,而不是动态添加的?
或者,是否有更好的方法可以重新使用动态添加的列而不删除它们并重新添加它们(使用更正后的ID)?如上所述它们在那里,但是单元格没有数据,并且当我在回发期间返回网格时,单元格中的标签ID都被更改,所以我找不到它们来恢复它们的值。
答案 0 :(得分:0)
您可以尝试使用数据表而不是在gridview中添加列,它曾经与我很好地工作,您只需要初始化数据表并添加任意数量的列和行,并在if结束时pageload上的(!IsPostback)将gridview绑定到datatable,而无需定义gridview_rowdatabound。 例如:
if (!Page.IsPostBack) {
foreach (string s in mydictionary.Keys) {
dt1.Columns.Add(s);
}
DataRow dr = dt.NewRow();
foreach (column col in dt1.Columns) {
dr[i].value = mydictionary(col.columnname);
i = i + 1;
}
dt1.Rows.Add(dr);
gridview1.datasource = dt1;
gridview1.databind();
}
我从vb.net转换为C#请在发生错误时通知我。 让gridgene = true
中的自动生成列