開源DataGridView擴展(5) 簡單實現統計行,有更好的方法嗎?


一、需要嗎?

我們的假設前提有一下:

1)你是一個Winform開發者。

2)你現在要用Grid實現你的需求。

3)你們項目組不准用三方控件。

4)你的需求中就偏偏需要對信息的統計。

如果你具備了上述的條件,那么你需要它。統計信息往往在表格中是比較重要的地位的,下面我們來看如何來實現:

r0

二、能實現嗎?

      相對於其他的控件擴展,遇到這么個問題,我一開始真是無從下手;因為.Net的DataGridView本身就沒有實現統計行,那么想擴展就找不到一個支點。

      我簡閱了很多的實現統計行的代碼,有使用panel的有、有使用雙DataGridView的;各式各樣,不缺乏好的方案,但是我覺得唯一的缺憾就是他們都不來自DataGridView的自身擴展,也只能算個變通的實現方法。

      經過我仔細的思考,既然沒有現成的統計行,那么就利用Row來擴展,需要做到以下幾點;

     1)能實現統計行,添加統計信息;

     2)統計行的單元格與表格保持一致,隨着列寬的改變而改變,保持表格樣式。

     3)統計行要始終保持在最下方,不能隨着排序等變動位置。

     4)統計行的數據應該不跟一般的行一起獲取。

先說說我的實現方法吧:

1. 先實現一個SummaryRow和SummaryCell

   1:  namespace DataGridViewEx.DataGridViewExs.RowEx
   2:  {
   3:      /// <summary>
   4:      /// 統計行
   5:      /// </summary>
   6:      public class DataGridSummaryRowEx:DataGridViewRow
   7:      {
   8:           
   9:      }
  10:   
  11:      /// <summary>
  12:      /// 統計單元格
  13:      /// </summary>
  14:      public class DataGridSummaryCellEx : DataGridViewTextBoxCell
  15:      {
  16:          protected override void OnClick(DataGridViewCellEventArgs e)
  17:          {
  18:              
  19:              //base.OnClick(e);
  20:          }
  21:   
  22:          public override bool ReadOnly
  23:          {
  24:              get
  25:              {
  26:                  return true;
  27:              }
  28:              set
  29:              {
  30:                  base.ReadOnly = value;
  31:              }
  32:          }
  33:      }
  34:  }

 

2. 在DataGridViewEx的CellPainting等事件中把SummaryCell過濾,不做處理。

   1:         protected override void OnCellFormatting(DataGridViewCellFormattingEventArgs e)
   2:          {
   3:              if (this.Rows[e.RowIndex].Cells[e.ColumnIndex] is utGridSummaryCell)
   4:                  return;
   5:              //Mark:在這里執行注冊的程序
   6:              this.CellFormatterRegister.RunFormatter(this.Columns[e.ColumnIndex].Name, e);
   7:              //....
   8:          }

 

3. 在 DataGridViewEx中的ColumnHeaderClick中處理,先Remove統計行,再添加統計行。(主要是解決排序的問題)

   1:   /// <summary>
   2:          /// 在排序之前將統計行去除,使得排序不會根據統計行內容排序
   3:          /// </summary>
   4:          /// <param name="e"></param>
   5:          protected override void OnColumnHeaderMouseClick(DataGridViewCellMouseEventArgs e)
   6:          {
   7:              if (e.Button == System.Windows.Forms.MouseButtons.Left)
   8:                  this.RemoveSummaryRow();
   9:              base.OnColumnHeaderMouseClick(e);
  10:              if (e.Button == System.Windows.Forms.MouseButtons.Left)
  11:                  this.AppendSummaryRow();
  12:          }
  13:   
  14:   
  15:          DataGridSummaryRowEx m_summaryRow = null;
  16:   
  17:          private void RemoveSummaryRow()
  18:          {
  19:              if (m_summaryRow == null) return;
  20:              if (this.Rows.Contains(m_summaryRow))
  21:                  this.Rows.Remove(m_summaryRow);
  22:          }
  23:   
  24:          private void AppendSummaryRow()
  25:          {
  26:              if (m_summaryRow == null) return;
  27:              this.RemoveSummaryRow();
  28:              int index = this.Rows.Add(m_summaryRow);
  29:              m_summaryRow = this.Rows[index] as DataGridSummaryRowEx;
  30:          }
  31:   
  32:          /// <summary>
  33:          /// 創建統計行,並且返回統計行對象,以便對單元格進行賦值信息
  34:          /// </summary>
  35:          /// <returns></returns>
  36:          static Color m_summaryBackColor = Color.Linen;
  37:          public DataGridSummaryRowEx CreateSummary()
  38:          {
  39:              if (m_summaryRow == null)
  40:              {
  41:                  m_summaryRow = new DataGridSummaryRowEx();
  42:   
  43:                  //添加與column相同的列,只是這里的單元格是自擴展的。
  44:                  foreach (DataGridViewColumn col in this.Columns)
  45:                  {
  46:                      m_summaryRow.Cells.Add(new DataGridSummaryCellEx());
  47:                  }
  48:                  m_summaryRow.DefaultCellStyle.BackColor = m_summaryBackColor;
  49:              }
  50:              this.RemoveSummaryRow();
  51:              this.AppendSummaryRow();
  52:              return m_summaryRow;
  53:          }

 

4. 看到那個CreateSummary 方法了嗎,就是用這個方法添加的:

   1:     protected void IniailzieData()
   2:          {
   3:              for (int i = 0; i < 10; i++)
   4:              {
   5:                  this.dataGridViewEx1.Rows.Add(new object[] { 
   6:                      false,"測試文本"+i,"","btn"+i
   7:                  });
   8:              }
   9:   
10: DataGridSummaryRowEx summaryRow = this.dataGridViewEx1.CreateSummary(); 11: summaryRow.Cells[0].Value = "合計"; 12: summaryRow.Cells[2].Value = 122;
  13:          }

三、有更好的方法嗎?

先介紹一下我的實現原理吧:

1)設計一個CreateSummary方法在行尾添加一個統計行。

2)這個統計行,不使用DataGridView中的列信息,而是使用列數和列寬來使用SummaryCell來自定義一行。

3)這個統計行,在ColumnHeaderClick中先移除再添加,主要解決的是在排序之前把它移除,排序就不在內,然后添加到最后一行。

4)把這個行放出去,然后由外面來賦值,要實現自動統計還是比較麻煩的。

好了,介紹完我的實現方法,現求更好的方法,或者完善我的方法。

1) 我的方法中不能實現自動統計。

2) 我的方法中CreateSummary必須人為的在最后調用,所以不夠安全。

3) 我的方法中使用枚舉Rows時,也帶了統計行信息。

由於有了這么多弊端,所以現求大牛們能否思考如果解決我的這些問題,或者能否有更好的實現思路。

四、源碼及演示程序下載。

演示程序: 05[20120515]SummaryRow@DataGridViewEx.rar

開源項目:http://sourceforge.net/p/datagridviewex/code-0/3/tree/trunk/DataGridViewEx/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM