2016-02-16 2 views
7

У меня есть 2 Gridviews. В первой сетке есть кнопка, которая при нажатии будет заполнять вторую сетку данными, основанными на идентификаторе кнопки, нажатой.call RowDataBound от другой функции

У меня тогда есть код в функции RowDataBound, чтобы показать сетку на основе выбранной строки. Но проблема в том, что код автоматически запускает RowDataBound перед функцией заполнения. Таким образом, вторая сетка не отображается.

Код для GridView:

<asp:GridView style="width:75%" 
         ID="gvCVRT" 
         ShowHeaderWhenEmpty="true" 
         CssClass="tblResults" 
         runat="server" 
         OnRowDataBound="gvCVRT_RowDataBound" 
         OnSelectedIndexChanged="gridviewParent_SelectedIndexChanged"       
         DataKeyField="ID" 
         DataKeyNames="ChecklistID" 
         AutoGenerateColumns="false" 
         allowpaging="false" 
         AlternatingRowStyle-BackColor="#EEEEEE"> 
         <HeaderStyle CssClass="tblResultsHeader" /> 
         <Columns> 
          <asp:BoundField DataField="ChecklistID" HeaderText="ID" ></asp:BoundField> 
          <asp:CommandField ShowSelectButton="True" HeaderText="Select" /> 
          <asp:BoundField DataField="ChecklistDate" HeaderText="Checklist Date" dataformatstring="{0:dd/MM/yyyy}"></asp:BoundField> 
          <asp:BoundField DataField="User" HeaderText="User" ></asp:BoundField> 
          <asp:BoundField DataField="Note" HeaderText="Note" ></asp:BoundField> 

         </Columns> 
        </asp:GridView> 

Код позади:

protected void gvCVRT_RowDataBound(object sender, GridViewRowEventArgs e) 
{ 
    if (e.Row.RowType == DataControlRowType.DataRow) 
    { 
     lookupCVRT work = (lookupCVRT)e.Row.DataItem; 
     GridView gv = sender as GridView; 

     if (work.ID != null) 
     { 
      int index = gv.Columns.HeaderIndex("Select"); 
      if (index > -1) 
      { 
       e.Row.Cells[index].Attributes.Add("class", "gvCVRTRow"); 
       e.Row.Cells[index].ToolTip = "Click here to Edit Checklist"; 
      } 
     } 
    } 
} 

Код для кнопки выбора:

protected void gridviewParent_SelectedIndexChanged(object sender, EventArgs e) 
{ 
    List<lookupCVRT> workDetails = lookupCVRT.GetChecklistItemsByChecklistID(Company.Current.CompanyID, ParentID.ToString(), gvCVRT.SelectedDataKey.Value.ToString()); 
    gvCVRTDetails.DataSource = workDetails; 
    gvCVRTDetails.DataBind(); 
    FireJavascriptCallback("setArgAndPostBack();"); 
} 

Таким образом, проблема, когда я нажимаю на кнопку Выбрать в сетью он запускает RowDataBound сначала, а затем gridviewParent_SelectedIndexChanged, но мне нужно запустить gridviewParent_SelectedIndexChanged первый. Могу ли я позвонить функции RowDataBound с gridviewParent_SelectedIndexChanged?

Page_Load функция:

protected void Page_Load(object sender, EventArgs e) 
    { 
     if (!Page.IsPostBack) 
     { 
      GetChecklistID = ""; 
      if (ParentID.HasValue) 
      { 
       ViewState["ParentID"] = ParentID; 

       List<lookupCVRT> work = lookupCVRT.GetCVRTItems(Company.Current.CompanyID, ParentID.ToString()); 
       ViewState["CVRT"] = work; 
       gvCVRT.DataSource = work; 
       gvCVRT.DataBind(); 

      } 
     } 
     else 
     { 
      if (ViewState["ParentID"] != null) 
      { 
       ParentID = (int?)ViewState["ParentID"]; 
       List<lookupCVRT> work = ViewState["CVRT"] as List<lookupCVRT>; 
       gvCVRT.DataSource = work; 
       gvCVRT.DataBind(); 

      } 
     } 
    } 
+0

Можете ли вы опубликовать свой метод Page_Load и все другие методы, которые содержат падение на DataBind()? – Markus

+0

@Markus добавить код__загрузки на мой вопрос. Это единственное место, которое вызывается DataBind. Когда я нажимаю на select, он переходит в 'else' часть метода – user123456789

+0

thanks; Я думаю, что я определил проблему; см. мой обновленный ответ. – Markus

ответ

1

OnRowDataBound событие вызывается только если метод DataBind для GridView был вызван.

В вашем конкретном случае, проблема заключается в Page_Load в else ветви условия Page.IsPostBack:

else 
{ 
    if (ViewState["ParentID"] != null) 
    { 
     ParentID = (int?)ViewState["ParentID"]; 
     List<lookupCVRT> work = ViewState["CVRT"] as List<lookupCVRT>; 
     gvCVRT.DataSource = work; 
     gvCVRT.DataBind(); 

    } 
} 

Этот код выполняется для каждого постбэка. Если вы не сбросите ViewState["ParentID"] где-то еще в своем коде, то при каждом обратном вызове вы снова привяжете GridView gvCVRT. Именно по этой причине вызывается RowDataBound. По окончании Page_Load страница вызывает дополнительные обработчики событий, в вашем случае gridviewParent_SelectedIndexChanged.

Для того, чтобы решить эту проблему, необходимо изменить код в Page_Load обработчика, так что нет звонков в DataBind для постбэка:

// field moved to class level so that you can access this variable instead of a DataRow in gvCVRT 
private List<lookupCVRT> work; 

protected void Page_Load(object sender, EventArgs e) 
{ 
    if (!Page.IsPostBack) 
    { 
     GetChecklistID = ""; 
     if (ParentID.HasValue) 
     { 
      ViewState["ParentID"] = ParentID; 

      work = lookupCVRT.GetCVRTItems(Company.Current.CompanyID, ParentID.ToString()); 
      ViewState["CVRT"] = work; 
      gvCVRT.DataSource = work; 
      gvCVRT.DataBind(); 

     } 
    } 
    else 
    { 
     if (ViewState["ParentID"] != null) 
     { 
      ParentID = (int?)ViewState["ParentID"]; 
      work = ViewState["CVRT"] as List<lookupCVRT>; 
     } 
    } 
} 

Основной причиной вашей проблемы является то, что вам нужно данные в запросе обратной передачи и что вы помещаете их в ViewState["CVRT"] вместо запроса данных заново. В веб-приложениях довольно часто считываются данные для нового запроса. Таким образом, вы можете подумать о том, действительно ли вам нужно поместить данные в ViewState или вы можете запросить их после обратной передачи из источника данных.

Ввод данных в ViewState увеличивает размер страницы, переданной клиенту (в основном у вас есть HTML для GridView и, кроме того, у вас есть данные в ViewState). Поэтому в большинстве случаев запрос их заново будет лучшим способом.

+0

Но «Gridview» привязывается при нажатии на клик, потому что мне нужно получить идентификатор из выбранной строки: 'gvCVRT.SelectedDataKey.Value.ToString()'. Я не могу сделать это из page_load, потому что у меня еще нет идентификатора. – user123456789

+0

@ user123456789: Да, я это понимаю. Я снова прочитал ваш вопрос, и меня все больше путают имена элементов управления и обработчиков событий. Чтобы уточнить: у вас есть GridView 'gvCVRT', который является родителем с обработчиками событий« gridviewParent_SelectedIndexChanged »и' gvCVRT_RowDataBound'. Тогда есть дочерний GridView 'gvCVRTDetails', но в этом вопросе нет упоминаний обработчиков событий для дочернего GridView. С помощью 'RowDataBound' вы имеете в виду' gvCVRT_RowDataBound' или обработчик для дочернего GridView? – Markus

+0

@ user123456789: однако, 'RowDataBound' запускается только после вызова' DataBind'. Таким образом, было бы хорошим шагом проверить все вызовы на «DataBind» в вашем коде и, если они находятся в нужном месте. Если родительский GridView, например, привязан к данным в 'Page_Load', его' gvCVRT_RowDataBound' будет выполняться до 'gridviewParent_SelectedIndexChanged' и, скорее всего, уничтожит выделение. – Markus

0

Я не знаю, почему вы предпочли использовать gridviewParent_SelectedIndexChanged, тогда grdParent_RowDataBound ... Я создал для вас простое решение .. это могло бы помочь вам ..

<html xmlns="http://www.w3.org/1999/xhtml"> 
<head runat="server"> 
    <title></title> 
</head> 
<body> 
    <form id="form1" runat="server"> 
    <div> 
    <div> 
     <label>Parent Grid</label> 
     <asp:GridView ID="grdParent" runat="server" AutoGenerateColumns="false" 
      DataKeyField="Id" OnRowDataBound="grdParent_RowDataBound" OnRowCommand="grdParent_RowCommand"> 
      <Columns> 
       <asp:BoundField DataField="Name" HeaderText="Name" />     
       <asp:ButtonField CommandName="Details" HeaderText="Select" Text="Hello" ButtonType="Link" /> 
      </Columns> 
     </asp:GridView> 
    </div> 
    <div> 
     <label>child Grid</label> 
     <asp:GridView ID="grdChild" runat="server" AutoGenerateColumns="false" 
      DataKeyNames="ChildId" OnRowDataBound="grdChild_RowDataBound"> 
      <Columns> 
       <asp:BoundField DataField="Name" /> 
       <asp:BoundField DataField="Roll" />     
       <asp:ImageField HeaderText="Image" /> 
      </Columns> 
     </asp:GridView> 
    </div> 
    </div> 
    </form> 
</body> 
</html> 

Codebehind

public partial class Default2 : System.Web.UI.Page 
{ 
    protected void Page_Load(object sender, EventArgs e) 
    { 
     if (!IsPostBack) 
     { 
      List<ParentClass> pList = new List<ParentClass>() 
      { 
       new ParentClass{Id=5, Name="V"}, 
       new ParentClass{Id=6,Name="VI"}, 
       new ParentClass{Id=7,Name="VII"}, 
       new ParentClass{Id=8,Name="VIII"}, 
       new ParentClass{Id=9,Name="IX"}, 
       new ParentClass{Id=10,Name="X"}, 
      }; 

      grdParent.DataSource = pList; 
      grdParent.DataBind(); 
     } 
    } 

    protected void grdParent_RowDataBound(object sender, GridViewRowEventArgs e) 
    { 
     if (e.Row.DataItem == null || e.Row.RowType != DataControlRowType.DataRow) 
     { 
      return; 
     } 

     ParentClass p = e.Row.DataItem as ParentClass; 

     var btn = e.Row.Cells[1].Controls[0] as LinkButton; 
     btn.CommandArgument = p.Id.ToString(); 
    } 

    protected void grdParent_RowCommand(object sender, GridViewCommandEventArgs e) 
    { 
     int parentId = Convert.ToInt32(e.CommandArgument); 

     var releventStudents = GetRepositary().FindAll(i => i.ParentId == parentId); 

     grdChild.DataSource = releventStudents; 
     grdChild.DataBind(); 

    } 

    protected void grdChild_RowDataBound(object sender, GridViewRowEventArgs e) 
    { 
     if (e.Row.DataItem == null || e.Row.RowType != DataControlRowType.DataRow) 
     { 
      return; 
     } 

     //lookupCVRT work = (lookupCVRT)e.Row.DataItem; 
     //GridView gv = sender as GridView; 

     //if (work.ID != null) 
     //{ 
     // int index = gv.Columns.HeaderIndex("Select"); 
     // if (index > -1) 
     // { 
     //  e.Row.Cells[index].Attributes.Add("class", "gvCVRTRow"); 
     //  e.Row.Cells[index].ToolTip = "Click here to Edit Checklist"; 
     // } 
     //}   
    } 

    private List<ChildClass> GetRepositary() 
    { 
     List<ChildClass> allChild = new List<ChildClass>(); 
     Random r = new Random(); 

     for (int i = 0; i < 50; i++) 
     { 
      ChildClass c = new ChildClass 
      { 
       ChildId = i, 
       ParentId = r.Next(5, 10), 
       Name = "Child Name " + i, 
       Roll = i 
      }; 

      allChild.Add(c); 
     } 

     return allChild; 
    } 
} 

public class ParentClass 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
} 

public class ChildClass 
{ 
    public int ParentId { get; set; } 
    public int ChildId { get; set; } 
    public int Roll { get; set; } 
    public string Name { get; set; } 
} 
Смежные вопросы