2013-09-24 27 views
0

我有一個基於用戶查詢動態生成列的GridView。 這意味着有時候我可以有1列xxx列的名稱,或者我最多可以有4列。GridvView FooterRow總計

所以:()表示可選

AAA | (BBB) | (CCC) | (DDD) 

1  7  45  2 
22  9  6  33 
... ...  ...  ... 

我需要總結每一列的總計不知道哪些列將一直持續到程序運行。

我想使用e.RowType == DataControlRowType.Footer部分的GridView_RowDataBound事件,但我似乎無法弄清楚如何讓它工作。

我通過事件的e.Row.RowType == DataControlRowType.DataRow部分保存變量中的運行總數,但我似乎無法弄清楚如何將保存的項目「注入」到頁腳基於可用列的網格。

任何人都可以給我一點幫助嗎?

編輯

的GridView與基本標誌了,因爲列動態構建完成。

<asp:GridView ID="gv" runat="server" ShowFooter="true" nRowDataBound="gv_RowDataBound"> 
</asp:GridView> 

然後在列代碼:

private void BindGrid() 
{ 
    DataTable dt = new DataTable(); 
        var stt = from t in edcQuery.ToList() 
          where t.Technician.TeamId == 1 
          orderby t.RequestType.Name 
          select new 
          { 
           RequestType = t.RequestType.Name, 
           Tech = t.Technician.Name, 
          }; 
        dt.Columns.Add("Support Ticket Type"); 
        DataRow dr; 
        foreach (var col in stt.OrderBy(x => x.Tech).GroupBy(x => x.Tech)) 
        { 
         dt.Columns.Add(col.Key.Substring(0, col.Key.IndexOf(' ')).Trim()); 
        } 
        foreach (var type in stt.GroupBy(x => x.RequestType)) 
        { 
         dr = dt.NewRow(); 
         dr["Support Ticket Type"] = type.Key; 
         foreach (var tech in type.GroupBy(x => x.Tech)) 
         { 
          dr[tech.Key.Substring(0, tech.Key.IndexOf(' ')).Trim()] = (object)tech.Count() == System.DBNull.Value ? 0 : tech.Count(); 
         } 
         dt.Rows.Add(dr); 
        } 

        //gvEDCSupportTicketType.FooterRow.Cells[2].Text = "0"; 
        gvEDCSupportTicketType.DataSource = dt; 
        gvEDCSupportTicketType.DataBind(); 
} 

double atot = 0.0; 
double btot = 0.0; 
double ctot = 0.0; 
double dtot = 0.0; 
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e) 
{ 
if (e.Row.RowType == DataControlRowType.DataRow) 
    { 
     var dataRow = (DataRowView)e.Row.DataItem; 

     string[] columnNames = { "AAA", "BBB", "CCC", "DDD" }; 

    foreach (var item in columnNames) 
     { 
      var checkName = dataRow.Row.Table.Columns.Cast<DataColumn>().Any(x => x.ColumnName.Equals(item, StringComparison.InvariantCultureIgnoreCase)); 

      if (checkName) 
      { 
       if (DataBinder.Eval(e.Row.DataItem, item) != DBNull.Value && Convert.ToInt32(DataBinder.Eval(e.Row.DataItem, item)) != 0) 
       { 
        switch (item) 
        { 
         case "AAA": 
          atot += Convert.ToInt32(DataBinder.Eval(e.Row.DataItem, item)); 
          break; 
         case "BBB": 
          btot += Convert.ToInt32(DataBinder.Eval(e.Row.DataItem, item)); 
          break; 
         case "CCC": 
          ctot += Convert.ToInt32(DataBinder.Eval(e.Row.DataItem, item)); 
          break; 
         case "DDD": 
          dtot += Convert.ToInt32(DataBinder.Eval(e.Row.DataItem, item)); 
          break; 
        } 
       } 
      } 
     } 
    } 
    else if (e.Row.RowType == DataControlRowType.Footer) 
    { 
     e.Row.Cells[0].Text = "Totals:"; 
     e.Row.Cells[0].Attributes.Add("style", "text-align: right;"); 

    } 
} 

所以你可以看到,它建立從數據表網格和只使用在運行時需要的列。沒有靜態的FooterTemplate或任何東西。

+1

你能發表一些代碼嗎? GridView定義和樣例綁定真的有幫助。 – Khan

+0

更新了原始文章中的代碼 – GenXisT

回答

1

我認爲你應該在下面使用try catch。

 else if (e.Row.RowType == DataControlRowType.Footer) 
{ 
    try 
    { 
    e.Row.Cells[0].Text = "Totals:" + atot.ToString(); 
    e.Row.Cells[0].Attributes.Add("style", "text-align: right;"); 
    } 
    catch 
    { 
    } 
    try 
    { 
    e.Row.Cells[1].Text = "Totals:" + btot.ToString(); 
    e.Row.Cells[1].Attributes.Add("style", "text-align: right;"); 
    } 
    catch 
    { 
    } 
    try 
    { 
    e.Row.Cells[2].Text = "Totals:" + ctot.ToString(); 
    e.Row.Cells[2].Attributes.Add("style", "text-align: right;"); 
    } 
    catch 
    { 
    } 
    try 
    { 
    e.Row.Cells[3].Text = "Totals:" + dtot.ToString(); 
    e.Row.Cells[3].Attributes.Add("style", "text-align: right;"); 
    } 
    catch 
    { 
    } 

} 

OR

 else if (e.Row.RowType == DataControlRowType.Footer) 
     { 
     int i = 0; 
     foreach (TableCell c in e.Row.Cells) 
     { 
      switch (i) 
      { 
       case 0: 
        c.Text = "Totals:" + atot.ToString(); 
        c.Attributes.Add("style", "text-align: right;"); 
        break; 
       case 1: 
        c.Text = "Totals:" + btot.ToString(); 
        c.Attributes.Add("style", "text-align: right;"); 
        break; 
       case 2: 
        c.Text = "Totals:" + ctot.ToString(); 
        c.Attributes.Add("style", "text-align: right;"); 
        break; 
       case 3: 
        c.Text = "Totals:" + dtot.ToString(); 
        c.Attributes.Add("style", "text-align: right;"); 
        break; 
      } 
      i++; 
     } 
     } 

所以,如果有頁腳單元格可用,它會經過否則去捕捉一部分。

+0

唯一的問題是BBB可能並不總是處於正確的索引位置。有時候,這可能是CCC甚至DDD。 唯一一個總是在正確的地方將是AAA。因此,舉例來說,我能有這樣的: AAA - CCC 或 AAA - BBB - DDD 但我也可以有 BBB - CCC 或 BBB - DDD 你知道我是什麼意思?並非所有列都將被使用,因爲它們基於查詢是動態的。因此,我不知道設計時的指數。 – GenXisT

+0

所以簡單的解決方案不是檢查它是哪個列名並保存它,只需將它與column1,column2,column3一起保存即可。因此,當您將它取回時,它的順序與您保存的順序相同。 – Hiren

+0

我實際上是通過在網格數據綁定之前添加一個簡單的循環並手動添加BoundFields來實現的。但既然你基本上把我引向正確的道路,並且我實現了一個類似於你在編輯中陳述的方法,你的答案是可以接受的。 – GenXisT