2013-10-12 4 views
0


решение проблемы с полем управления и шаблона GridView. Я определил GridView как это:ASP.NET GridView TemplateField элементы управления потеряли после PostBack

<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 кнопки для expland/Collapse дочерние элементы.

Если я НЕ НИЧЕГО с сеткой, отлично работает, событие после PostBacks. Но, поскольку есть много столбцов, у меня есть настройка, позволяющая настроить макет gridView, определяющий порядок столбцов и видимость. Если я что-то делаю с столбцами GridView (переупорядочить столбцы или просто удалить столбец и вставить его в ту же позицию), кнопки TemplateField теряются на PostBack. Даже если я ничего не делаю с определением столбца TemplateField, но переупорядочивая столбцы BoundFields, столбцы TemplateField теряются после PostBack.

Похоже, что есть проблема с ViewState (я не знаю). Дело в том, что:
1. Я делаю GridView настройку по методу Page_Init
2. я Связывание данных (из-за некоторых причин) по методу Page_PreRender, только если НЕ 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 событие пользовательского элемента управления, основной целью которого является для привязки данных к сетке: -) событие инициируется вызовом DataBind в методе Page_PreRender родительского элемента управления, например:

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(); 
    } 

Hopes это помощь.

ответ

3

Ваше Viewstate, «потеряно» при обратной передаче, потому что вы изменили структуру GridView. Шаблоны TemplateField все еще существуют, но ... Если вы добавите/удалите столбцы после OnInit, но до того, как ваш GridView будет привязан к базе данных, у вас не будет этой проблемы. Я думаю, что для вашей проблемы, хотя вам нужно будет переустановить данные в GridView после удаления столбцов, чтобы обновить ViewState.

ИЛИ, я нашел это возможное решение тоже, похоже на вызов myGridView.Columns.Clear(); прежде чем добавлять/удалять столбцы, может сделать трюк для вас.

http://forums.asp.net/p/1229438/2216336.aspx#2216336

+0

Благодарим Брайана за ваш ответ. Но: я добавляю/удаляю столбцы в методе Page_Init, поэтому до того, как мой GridView будет привязан к базе данных, и это не нормально. Поэтому я не понимаю, почему это не должно работать ... Я привязываю данные, когда структура gridView установлена ​​и не изменена позже. Предлагаемое второе возможное решение в моем решении для решения проблемы ... Я могу попробовать это, но я хотел бы понять, что я делаю неправильно и как это делать должным образом. Тем не менее, спасибо. – 12moyo34

+0

Хорошо опубликуйте свой код, чтобы я мог видеть, что вы делаете «неправильно». Потому что вещи должны быть найдены, если столбцы добавляются/удаляются до того, как GridView привязан к данным. Возможно, вы удаляете неверный индекс столбца? (Столбец (i)) –

+0

Хорошо, я отправлю его в следующем ответе. BTW, решение обходного решения работает, но в любом случае, я хочу знать, что я делаю неправильно :-) – 12moyo34

0

на основе кода за добавленного к вашему вопросу, то проблема может быть, что ваша привязка данных слишком поздно, чтобы GridView работать правильно. Это должно быть сделано в Page_Load. Я думаю, что здесь есть красный флаг, который вы вызываете TasksTreeView.DataBind() в OnDataBinding, а также снова вызываете DataBind в собственном элементе управления в SetView на основе события в жизненном цикле ASP.NET.

Также почему вы вызываете DataBind снова в protected override void OnDataBinding. Вы вызвали DataBind где-то уже, чтобы вызвать OnDataBinding. Вы запускаете защищенный переопределить void OnDataBinding на своей родительской странице в конечном счете через вызов SetView настраиваемого элемента управления viewControl.DataBind()? Если это так, то это какой-то запутанный, неподдающийся безопасности код, и вы должны реструктурировать, чтобы ваша родительская страница и пользовательский элемент управления были связаны друг с другом, чтобы вы могли повторно использовать настраиваемый элемент управления, не имея разработчика, который должен знать внутреннюю работу настраиваемого элемента управления.

Если у вашего CustomControl нет общедоступного метода DataBind, который работает так, как вы хотите, чем создать новый общедоступный метод, который имитирует параметры DataBind GridView DataBind, а затем вызывает соответствующий GridView с переданным в аргументе данных.

Возможно, вы можете перестроить свой код и устранить метод SetView. Вы не должны вызывать DataBind в настраиваемом элементе управления. Это должно быть до родительского пользователя настраиваемого элемента управления, когда вызывается DataBind. Override DataBind в пользовательском элементе управления вместо:

общественного переопределение недействительного DataBind() { реализация //...some здесь ... base.DataBind() }

0

Set EnableViewState к ложному на вашем .aspx. У меня была эта проблема, и это решило проблему для меня.

Смежные вопросы