我在GridView中动态添加列时遇到问题.我需要根据DropDownList中的值来更改布局(即包含的列).当用户更改此列表中的选择时,我需要删除除第一列之外的所有内容,并根据选择动态添加其他列.
我的标记中只有一列 – 列0,一个模板列,其中我声明一个选择链接和另一个应用程序特定的LinkButton.那个列需要永远在那里.当创建ListBoxSelection时,我删除除第一列之外的所有列,然后重新添加所需的列(在此示例中,我简化了它以始终添加“标题”列).以下是代码的一部分:
RemoveVariableColumnsFromGrid(); BoundField b = new BoundField(); b.DataField = "Title"; this.gvPrimaryListView.Columns.Add(b); this.gvPrimaryListView.DataBind(); private void RemoveVariableColumnsFromGrid() { int ColCount = this.gvPrimaryListView.Columns.Count; //Leave column 0 -- our select and view template column while (ColCount > 1) { this.gvPrimaryListView.Columns.RemoveAt(ColCount - 1); --ColCount; } }
该代码第一次运行时,我看到静态列和动态添加的“标题”列.但是,下一次进行选择时,第一列生成为空(其中没有内容).我看到标题列,我看到左边的第一列 – 但是内部没有任何内容.在调试器中,我可以看到gvPrimaryListView确实还有两列,第一列(索引0)确实是一个模板列.实际上,列甚至保留了下面标记中设置为165px的宽度(用于调试目的).
有任何想法吗?
<asp:GridView ID="gvPrimaryListView" runat="server" Width="100%" AutoGenerateColumns="false" DataKeyNames="Document_ID" EnableViewState="true" DataSourceID="odsPrimaryDataSource" AllowPaging="true" AllowSorting="true" PageSize="10" OnPageIndexChanging="activeListView_PageIndexChanging" AutoGenerateSelectButton="False" OnSelectedIndexChanged="activeListView_SelectedIndexChanged" Visible="true" OnRowDataBound="CtlDocList_RowDataBound" Font-Size="8pt" Font-Names="Helvetica"> <Columns> <asp:TemplateField ShowHeader="false"> <ItemTemplate> <asp:LinkButton EnableTheming="false" ID="CtlSelectDocRowBtn" runat="server" Text="Select" CommandName="Select" CssClass="gridbutton" OnClick="RowSelectBtn_Click" /> <asp:ImageButton EnableTheming="false" ID="DocViewBtn" runat="server" ImageUrl="../../images/ViewDoc3.png" CssClass="gridbutton" CommandName="Select" OnClick="DocViewBtn_Click" /> </ItemTemplate> <ItemStyle Width="165px" /> </asp:TemplateField> </Columns> <EmptyDataTemplate> <asp:Label ID="Label6" runat="server" Text="No rows found." SkinID="LabelHeader"></asp:Label> </EmptyDataTemplate> </asp:GridView>
只是一些额外的信息.
它与第一列无关,但它与TemplateField的事实有关.如果我将一个普通的列放在左边(在标记中),并且将TemplateField列移到右边,那么第一列渲染得很好,(现在第二个)TemplateField列消失.
另一个奇怪的事情 – 问题不会发生在第一次回发 – 或第二 – 但它开始于第三个回发,然后继续后续的回发.我被困了
解决方法
我最近在网格视图中征服了动态列的类似问题,也许这将有所帮助.
首先关闭viewstate
第二,在oninit事件触发的函数中以列表方式添加列
最后,我使用以下帮助器类来使得复选框在RowDataBound事件启动时实例化.是的,有些是硬编码.
这里是所有的代码.有在这里:) Warrenty as is,blah blah blah …
最后,因为我刚刚得到我的脚湿DotNet任何提示将不胜感激[IE不要撕我太多:)].是的,“借用”网站上的初始代码,对不起,我不记得我的头顶
– 在受保护的覆盖范围内将其释放掉OnInit
private void GridViewProject_AddColumns() { DataSet dsDataSet = new DataSet(); TemplateField templateField = null; try { StoredProcedure sp = new StoredProcedure("ExpenseReportItemType_GetList","INTRANETWEBDB",Context.User.Identity.Name); dsDataSet = sp.GetDataSet(); if (sp.RC != 0 && sp.RC != 3000) { labelMessage.Text = sp.ErrorMessage; } int iIndex = 0; int iCount = dsDataSet.Tables[0].Rows.Count; string strCategoryID = ""; string strCategoryName = ""; iStaticColumnCount = GridViewProject.Columns.Count; // Insert all columns immediatly to the left of the LAST column while (iIndex < iCount) { strCategoryName = dsDataSet.Tables[0].Rows[iIndex]["CategoryName"].ToString(); strCategoryID = dsDataSet.Tables[0].Rows[iIndex]["CategoryID"].ToString(); templateField = new TemplateField(); templateField.HeaderTemplate = new GridViewTemplateExternal(DataControlRowType.Header,strCategoryName,strCategoryID); templateField.ItemTemplate = new GridViewTemplateExternal(DataControlRowType.DataRow,strCategoryID); templateField.FooterTemplate = new GridViewTemplateExternal(DataControlRowType.Footer,strCategoryID); // Have to decriment iStaticColumnCount to insert dynamic columns BEFORE the edit row GridViewProject.Columns.Insert((iIndex + (iStaticColumnCount-1)),templateField); iIndex++; } iFinalColumnCount = GridViewProject.Columns.Count; iERPEditColumnIndex = (iFinalColumnCount - 1); // iIndex is zero based,Count is not } catch (Exception exception) { labelMessage.Text = exception.Message; } }
– 助手班
public class GridViewTemplateExternal : System.Web.UI.ITemplate { #region Fields public DataControlRowType DataRowType; private string strCategoryID; private string strColumnName; #endregion #region Constructor public GridViewTemplateExternal(DataControlRowType type,string ColumnName,string CategoryID) { DataRowType = type; // Header,DataRow,strColumnName = ColumnName; // Header name strCategoryID = CategoryID; } #endregion #region Methods public void InstantiateIn(System.Web.UI.Control container) { switch (DataRowType) { case DataControlRowType.Header: // build the header for this column Label labelHeader = new Label(); labelHeader.Text = "<b>" + strColumnName + "</b>"; // All CheckBoxes "Look Up" to the header row for this information labelHeader.Attributes["ERICategoryID"] = strCategoryID; labelHeader.Style["writing-mode"] = "tb-rl"; labelHeader.Style["filter"] = "flipv fliph"; container.Controls.Add(labelHeader); break; case DataControlRowType.DataRow: CheckBox checkBoxAllowedRow = new CheckBox(); checkBoxAllowedRow.Enabled = false; checkBoxAllowedRow.DataBinding += new EventHandler(this.CheckBox_DataBinding); container.Controls.Add(checkBoxAllowedRow); break; case DataControlRowType.Footer: // No data handling for the footer addition row CheckBox checkBoxAllowedFooter = new CheckBox(); container.Controls.Add(checkBoxAllowedFooter); break; default: break; } } public void CheckBox_DataBinding(Object sender,EventArgs e) { CheckBox checkBoxAllowed = (CheckBox)sender;// get the control that raised this event GridViewRow row = (GridViewRow)checkBoxAllowed.NamingContainer;// get the containing row string RawValue = DataBinder.Eval(row.DataItem,strColumnName).ToString(); if (RawValue.ToUpper() == "TRUE") { checkBoxAllowed.Checked = true; } else { checkBoxAllowed.Checked = false; } } #endregion }