2016-02-16 62 views
7

的RowDataBound我有一個2個GridView的。第一個網格有一個按鈕,當點擊它時,它會根據點擊的按鈕的ID填充第二個網格。從另一個調用函數

然後我必須在的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但我需要運行012首先是。我可以從gridviewParent_SelectedIndexChanged撥打RowDataBound功能嗎?

的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方法以及包含跌倒數據綁定所有其他方法()? – Markus

+0

@Markus將Page_Load代碼添加到我的問題中。這是DataBind被調用的唯一地方。當我點擊select時,它會進入方法 – user123456789

+0

的'else'部分,謝謝;我想我已經確定了這個問題。請看我最新的答案。 – Markus

回答

1

如果爲GridViewDataBind方法被稱爲OnRowDataBound事件,纔會調用。

在特定情況下,問題是Page_Load中的Page.IsPostBack條件else分支:

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"]而不是重新請求數據。在Web應用程序中,再次讀取數據以用於新請求是很常見的。因此,您可能會考慮是否真的需要將數據放入ViewState,或者是否可以通過數據源的回發請求它們。

將數據放入ViewState中增加了傳送到客戶端的頁面的大小(基本上你必須爲GridView的HTML,此外你必須在ViewState中的數據)。因此,在大多數情況下,重新申請它們將是更好的方式。

+0

但是'Gridview'被單擊select時綁定,因爲我需要從所選行中得到ID:'gvCVRT.SelectedDataKey.Value.ToString()'。我無法從page_load這樣做,因爲我還沒有ID。 – 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> 

代碼隱藏

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