解决 GridView 控件和模板字段的问题。我已经像这样定义了 GridView:
<asp:GridView ID="gridView" runat="server" ShowFooter="True" onrowdatabound="onRowDataBound" AutoGenerateColumns="False" onrowcreated="onRowCreated" onrowcommand="onRowCommand" onselectedindexchanged="onSelectedIndexChanged">
<Columns>
<asp:CommandField SelectText="cmdSelectRow" ShowSelectButton="True" />
<asp:TemplateField AccessibleHeaderText="treeController" HeaderText="">
<ItemTemplate>
<asp:ImageButton ID="btnShow" runat="server" ImageUrl="~\\Images\\treePlus.png" CommandName="TreeShow" UseSubmitBehavior="False"/>
<asp:ImageButton ID="btnHide" runat="server" Visible="False" ImageUrl="~\\Images\\treeMinus.png" CommandName="TreeHide" UseSubmitBehavior="False" />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="treeLevel" HeaderText="Tree Level" />
<asp:BoundField DataField="parentTaskId" HeaderText="parent_task_id" />
<asp:BoundField DataField="taskId" HeaderText="task_id" />
<asp:BoundField DataField="groupId" HeaderText="group_id" />
<asp:BoundField DataField="hasTiming" HeaderText="" />
... much more BoundFiels ...</Columns>
我想你明白使用这个 gridView 我实现了 treeView ...这两个 ImageButtons 是展开/折叠子项的按钮。
如果我对网格不做任何事情,则工作完美,在 PostBacks 之后发生事件。但是,因为有很多列,我有自定义允许调整定义列的顺序和可见性的 gridView 布局。如果我对 GridView 列执行任何操作(重新排序列,或者只是删除列并将其插入到同一位置),则 PostBack 上的 TemplateField 按钮会丢失。即使我没有对 TemplateField 列定义执行任何操作,而是对 BoundFields 列重新排序,在 PostBack 之后 TemplateField 列也会丢失。
看起来 ViewState 有问题(我不知道)。事实是:
1. 我在 Page_Init 方法上进行 GridView 自定义
2. 我在 Page_PreRender 方法上进行数据绑定(由于某些原因),只有在 NOT PostBack 的情况下
回发后,我看到几个问题解决了 TemplateField 项目的问题,但我没有找到解决方案。
有没有人的想法,应该是哪里的问题?为什么它有效,当gridview结构(列)没有做任何事情并且当同一列被取出并重新插入到网格列中时它不起作用?
感谢您的任何帮助或想法。
为了演示页面的“流程”,我添加了更多细节......
GridView 是我的自定义控件的一部分。
protected void Page_Init (object sender, EventArgs e)
{
/* customize grid control */
/* here I load the customization defined by user and change GridView.Columns */
layoutCustomize(gridControl, accountId);
}
如图所示,我正在更改 GridView 结构(在第一页加载或回发时)
protected override void OnDataBinding(EventArgs e)
{
/* declarations */
DbModel.TaskView [] tasks = null;
DataTable tasksTable = null;
/* call parent method */
base.OnDataBinding(e);
/* get data */
if ((tasks = TasksView.Data) != null)
{
/* build data table */
tasksTable = TsGridView.BuildDataTable(TasksTreeView, tasks, typeof(TaskView));
/* apply filter */
DataTable viewTable = Filter(tasksTable);
/* bound the data source to the gird */
TasksTreeView.DataSource = viewTable;
TasksTreeView.DataBind();
}
}
这是自定义控件的 DataBind 事件,主要目的是将数据绑定到网格 :-) 该事件是通过调用父控件的 Page_PreRender 方法中的 DataBind 来触发的,如下所示:
protected void Page_PreRender(object sender, System.EventArgs e)
{
/* set active view */
if (IsPostBack == false)
SetView(tasksMultiView.ActiveViewIndex);
}
protected void SetView (int viewIndex)
{
/* declarations */
Control viewControl = null;
View selectedView = null;
ListItem selectedItem = null;
/* get control */
selectedView = tasksMultiView.Views[viewIndex];
selectedItem = View.Items[viewIndex];
/* get control */
if ((viewControl = selectedView.FindControl(selectedItem.Value)) != null)
/* bind data */
viewControl.DataBind();
}
希望这有帮助。