2016-02-16 14 views
7

Ich habe eine 2 Gridviews. Das erste Raster hat eine Schaltfläche, die beim Klicken auf ein zweites Raster mit den Daten auf der Grundlage der ID der Schaltfläche, auf die geklickt wird, gefüllt wird.RowDataBound von einer anderen Funktion aufrufen

Ich habe dann Code in der RowDataBound-Funktion, um das Raster basierend auf der ausgewählten Zeile anzuzeigen. Das Problem ist jedoch, dass der Code automatisch RowDataBound vor der Populate-Funktion ausführt. Das zweite Raster wird also nicht angezeigt.

-Code für 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> 

-Code hinter:

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

-Code für Auswahltaste:

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

Also das Problem ist, wenn ich auf die Schaltfläche Auswählen klicken in der Gitter es läuft die RowDataBound zuerst dann die gridviewParent_SelectedIndexChanged aber ich muss 012 laufenzuerst. Kann ich die RowDataBound Funktion von gridviewParent_SelectedIndexChanged aufrufen?

Page_Load Funktion:

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

Können Sie bitte Ihre Page_Load-Methode und alle anderen Methoden veröffentlichen, die einen Sturz zu DataBind() enthalten? – Markus

+0

@Markus Seite_Load Code zu meiner Frage hinzufügen. Dies ist der einzige Ort, an dem DataBind aufgerufen wird. Wenn ich auf Select klicke, geht es in den 'else'-Teil der Methode – user123456789

+0

danke; Ich denke, ich habe das Problem identifiziert; Bitte sehen Sie meine aktualisierte Antwort. – Markus

Antwort

1

Das OnRowDataBound Ereignis wird nur aufgerufen, wenn die DataBind Methode zur GridView aufgerufen wurde.

In Ihrem speziellen Fall ist das Problem in Page_Load im else Zweig der Page.IsPostBack Bedingung:

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

    } 
} 

Dieser Code wird für jede Postbacks laufen. Sofern Sie ViewState["ParentID"] nicht irgendwo in Ihrem Code zurücksetzen, binden Sie die GridView gvCVRT erneut an jeden Postback. Dies ist der Grund, dass RowDataBound aufgerufen wird. Nach dem Beenden von Page_Load ruft die Seite die zusätzlichen Ereignishandler auf, in Ihrem Fall gridviewParent_SelectedIndexChanged.

Um dieses Problem zu lösen, müssen Sie den Code in Ihrem Page_Load Handler ändern, so dass es keine Anrufe DataBind für eine Postbacks sind:

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

Die Ursache des Problems ist, dass Sie brauchen die Daten in einer Postback-Anfrage und dass Sie diese in ViewState["CVRT"] setzen, anstatt die Daten erneut anzufordern. In Web-Anwendungen ist es üblich, die Daten für eine neue Anfrage erneut zu lesen. Sie könnten also darüber nachdenken, ob Sie die Daten wirklich in ViewState einfügen müssen oder ob Sie sie bei einem Postback von der Datenquelle anfordern können.

Durch das Einfügen der Daten in ViewState wird die Größe der Seite erhöht, die an den Client übertragen wird (im Grunde haben Sie den HTML-Code für die GridView und zusätzlich haben Sie die Daten in ViewState). Es wäre in den meisten Fällen besser, sie neu anzufragen.

+0

Aber die 'Gridview' wird gebunden, wenn select geklickt wird, weil ich die ID aus der ausgewählten Zeile holen muss: 'gvCVRT.SelectedDataKey.Value.ToString()'. Ich kann das nicht von page_load machen, weil ich die ID noch nicht habe. – user123456789

+0

@ user123456789: Ja, das verstehe ich. Ich habe Ihre Frage erneut gelesen und bin mehr und mehr verwirrt von den Namen der Steuerelemente und der Ereignishandler. Zur Verdeutlichung: Sie haben eine GridView 'gvCVRT', die das übergeordnete Element mit den Ereignishandlern' gridviewParent_SelectedIndexChanged' und 'gvCVRT_RowDataBound' ist. Dann gibt es eine untergeordnete GridView 'gvCVRTDetails', aber es gibt keine Erwähnung von Event-Handlern für die untergeordnete GridView in der Frage. Mit 'RowDataBound' meinst du' gvCVRT_RowDataBound' oder einen Handler für das untergeordnete GridView? – Markus

+0

@ user123456789: 'RowDataBound' wird jedoch nur nach einem Aufruf von' DataBind' ausgeführt. Es wäre also ein guter Schritt, alle Aufrufe von 'DataBind' in Ihrem Code zu überprüfen und ob sie an der richtigen Stelle sind. Wenn das übergeordnete GridView zum Beispiel datengebunden in 'Page_Load' ist, wird dessen' gvCVRT_RowDataBound' vor 'gridviewParent_SelectedIndexChanged' ausgeführt und zerstört höchstwahrscheinlich die Auswahl. – Markus

0

Ich weiß nicht, warum Sie lieber gridviewParent_SelectedIndexChanged dann grdParent_RowDataBound verwenden ... Ich habe eine einfache Lösung für Sie erstellt .. es könnte Ihnen helfen ..

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