2016-02-16 13 views
7

Ho 2 visualizzazioni Grid. La prima griglia ha un pulsante che quando viene cliccato popolerà una seconda griglia con i dati basati sull'id del pulsante cliccato.chiama RowDataBound da un'altra funzione

Quindi ho il codice nella funzione RowDataBound per mostrare la griglia in base alla riga selezionata. Ma il problema è che il codice esegue automaticamente RowDataBound prima della funzione populate. Quindi la seconda griglia non viene visualizzata.

Codice in materia di 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> 

codice dietro:

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"; 
      } 
     } 
    } 
} 

Codice per pulsante di selezione:

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

Quindi il problema è quando clicco sul pulsante Seleziona nella griglia corre il RowDataBound prima poi il gridviewParent_SelectedIndexChanged ma ho bisogno di eseguire 012 Prima il. Posso chiamare la funzione RowDataBound da gridviewParent_SelectedIndexChanged?

funzione 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

Potete per favore pubblicare il tuo metodo Page_Load e tutti gli altri metodi che contengono una caduta a DataBind()? – Markus

+0

@Markus aggiungi il codice Page_Load alla mia domanda. Questo è l'unico posto chiamato DataBind. Quando clicco su seleziona, entra nella parte 'else' del metodo – user123456789

+0

grazie; Penso di aver identificato il problema; per favore vedi la mia risposta aggiornata – Markus

risposta

1

L'evento OnRowDataBound viene chiamato solo se il metodo DataBind per la GridView è stato chiamato.

Nel vostro caso specifico, il problema è nella Page_Load nel ramo else della condizione Page.IsPostBack:

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

    } 
} 

Questo codice viene eseguito per ogni postback. A meno che non si ripristini ViewState["ParentID"] da qualche altra parte nel codice, su ogni postback si associa nuovamente il GridView gvCVRT. Questo è il motivo per cui viene chiamato RowDataBound. Dopo aver terminato il Page_Load, la pagina chiama i gestori di eventi aggiuntivi, nel tuo caso gridviewParent_SelectedIndexChanged.

Per risolvere questo problema, è necessario modificare il codice nel tuo Page_Load gestore in modo che non ci siano chiamate a DataBind per un postback:

// 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>; 
     } 
    } 
} 

La causa principale del problema è che avete bisogno i dati in una richiesta di postback e che li hai inseriti in ViewState["CVRT"] invece di richiedere nuovamente i dati. Nelle applicazioni web è piuttosto comune leggere di nuovo i dati per una nuova richiesta. Quindi potresti pensare se hai davvero bisogno di inserire i dati in ViewState o se puoi richiederli a un postback dall'origine dati.

Inserendo i dati in ViewState si aumenta la dimensione della pagina che viene trasferita al client (in pratica si ha l'HTML per GridView e in aggiunta si hanno i dati in ViewState). Quindi richiederli nuovamente sarebbe il modo migliore nella maggior parte dei casi.

+0

Ma il 'Gridview' viene associato quando si fa clic su select, perché ho bisogno di ottenere l'ID dalla riga selezionata: 'gvCVRT.SelectedDataKey.Value.ToString()'. Non riesco a farlo dal page_load perché non ho ancora l'ID. – user123456789

+0

@ user123456789: Sì, lo capisco. Ho letto di nuovo la tua domanda e sono sempre più confuso dai nomi dei controlli e dei gestori di eventi. Per chiarire: hai un GridView 'gvCVRT' che è il genitore con i gestori di eventi' gridviewParent_SelectedIndexChanged' e 'gvCVRT_RowDataBound'. Poi c'è un bambino GridView 'gvCVRTDetails', ma non ci sono menzioni di gestori di eventi per il bambino GridView nella domanda. Con 'RowDataBound' intendi' gvCVRT_RowDataBound' o un gestore per il figlio GridView? – Markus

+0

@ user123456789: tuttavia, 'RowDataBound' viene eseguito solo dopo una chiamata a' DataBind'. Quindi sarebbe un buon passo per controllare tutte le chiamate a 'DataBind' nel tuo codice e se sono nel posto giusto. Se il genitore GridView per esempio è legato ai dati in 'Page_Load', il suo' gvCVRT_RowDataBound' verrà eseguito prima di 'gridviewParent_SelectedIndexChanged' e molto probabilmente distruggerà la selezione. – Markus

0

Non so perché hai preferito utilizzare gridviewParent_SelectedIndexChanged quindi grdParent_RowDataBound ... ho creato una soluzione semplice per te .. potrebbe aiutarti ..

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