OutlookGrid 是一個繼承自 DataGridView 的開源 WinForms 控件,提供類似 Outlook 2003/2007 的資料分組、排序、摺疊/展開功能。專案採用 C# 2.0 / VS 2005 開發,原始碼開放,可自由修改擴展。
GroupTemplate 屬性支援預設分組、字母分組、日期分組(今日/本週/本月)等多種分組邏輯。DataSet/DataTable 綁定模式,也支援非綁定模式手動加入 OutlookGridRow。IComparer 實作(DataRowComparer、OutlookGridRowComparer),分組由 IOutlookGridGroup 介面實作。GetState 隱藏而非 Visible=false,避免基類重繪問題。// 1. 準備資料
var ds = new DataSet();
ds.ReadXml("invoices.xml"); // 包含 "invoice" Table
// 2. 綁定
outlookGrid1.BindData(ds, "invoice");
// 3. 設定分組模板(字母分組)
outlookGrid1.GroupTemplate = new OutlookGridAlphabeticGroup();
outlookGrid1.GroupTemplate.Column = outlookGrid1.Columns["CustomerName"];
outlookGrid1.GroupTemplate.Column.Collapsed = true; // 預設摺疊
// 4. 排序並自動分組
outlookGrid1.Sort(new DataRowComparer(outlookGrid1.Columns["CustomerName"].Index, SortOrder.Ascending));
outlookGrid1.BindData(null, null); // 清除綁定
outlookGrid1.Columns.Add("colId", "ID");
outlookGrid1.Columns.Add("colName", "名稱");
outlookGrid1.Columns.Add("colDate", "日期");
// 必須使用 OutlookGridRow
var row1 = new OutlookGridRow();
row1.CreateCells(outlookGrid1, 1, "客戶 A", DateTime.Today);
outlookGrid1.Rows.Add(row1);
var row2 = new OutlookGridRow();
row2.CreateCells(outlookGrid1, 2, "客戶 B", DateTime.Today.AddDays(-1));
outlookGrid1.Rows.Add(row2);
// 非綁定模式排序:直接指定欄位索引
outlookGrid1.GroupTemplate = new OutlookGridDefaultGroup();
outlookGrid1.GroupTemplate.Column = outlookGrid1.Columns[1];
outlookGrid1.Sort(outlookGrid1.Columns[1], SortOrder.Ascending);
| 類別 | 職責 |
|---|---|
OutlookGrid | 主控件,管理 RowTemplate、DataSourceManager、GroupTemplate,重寫 Paint/排序/滾動事件 |
OutlookGridRow | 擴充 IsGroupRow、Group 屬性,重寫 Paint/GetState 實現群組列外觀與摺疊邏輯 |
IOutlookGridGroup / OutlookGridDefaultGroup / OutlookGridAlphabeticGroup / OutlookGridDateTimeGroup | 分組邏輯封裝:CompareTo 判斷列屬於哪群組,Text 決定顯示文字,Clone 支援動態建立群組實例 |
DataSourceManager | 抽象層:索引綁定/非綁定資料,提供統一存取介面,支援將 OutlookGrid 自身作為資料來源 |
DataGridView 樣式(如 EnableHeadersVisualStyles)可能導致群組列繪製異常。OutlookGridRow.Paint 自行調整。VirtualMode,大量資料(>10萬列)效能未驗證。CellValuePushed 等事件。DoubleClick 已重寫作為摺疊/展開觸發)。public class OutlookGridCustomDateGroup : IOutlookGridGroup
{
public DataGridViewColumn Column { get; set; }
public bool Collapsed { get; set; }
public int CompareTo(object value)
{
if (value == null || value == DBNull.Value) return -1;
DateTime dt = Convert.ToDateTime(value);
DateTime today = DateTime.Today;
if (dt.Date == today) return 0; // 今日
if (dt.Date == today.AddDays(-1)) return 1; // 昨日
if (dt >= today.AddDays(-(int)today.DayOfWeek)) return 2; // 本週
if (dt.Month == today.Month && dt.Year == today.Year) return 3; // 本月
return 4; // 更早
}
public string Text { get; }
public object GroupValue { get; set; }
public object Clone() => new OutlookGridCustomDateGroup { Column = Column, Collapsed = Collapsed };
}
OutlookGrid 以極少代碼實現了 DataGridView 缺乏的分組功能,架構清晰、擴展性佳。雖有已知限制,但對於中小型專案、內部工具、快速原型開發,已足夠勝任。若需生產級大量資料、巢狀分組、雙向綁定編輯,建議評估商用控件(DevExpress XtraGrid、Telerik RadGridView)或自行基於 VirtualMode 重寫。