private static void AppendDataToGrid(DataGridView grid, IList<object> source) { int rowCount = grid.Rows.Count; List<DataGridViewRow> rows = new List<DataGridViewRow>(); Type t = source[0].GetType(); int rowIndex = grid.Rows.Add(); var girdCells = grid.Rows[rowIndex].Cells; //Common.ShowProcessing("正在加載數據,請稍候...", Common.MainForm, (o) => //{ foreach (object item in source) { var row = new DataGridViewRow(); foreach (DataGridViewCell cell in girdCells) { var p = t.GetProperty(cell.OwningColumn.DataPropertyName); object pValue = p.GetValue(item, null); var newCell = (DataGridViewCell)cell.Clone(); newCell.Value = pValue; row.Cells.Add(newCell); } rows.Add(row); } //}); grid.Rows.RemoveAt(rowIndex); grid.Rows.AddRange(rows.ToArray()); }
每二種方式,采用將數據源合並,然後重新綁定
protected void AppendDataToGrid<T,TResult>(DataGridView dataGridBase, IList<T> source,Func<T,TResult> orderBy) where T : class { //Stopwatch watch = new Stopwatch(); //watch.Start(); if (dataGridBase.Rows.Count > 0) { IEnumerable<T> bindsource = null; Common.ShowProcessing("正在加載數據,請稍候...", Common.MainForm, (o) => { var oldSource = (IList<T>)dataGridBase.DataSource; bindsource = source.Concat(oldSource).OrderBy(orderBy).ToList(); }); dataGridBase.DataSource = bindsource; } else { dataGridBase.DataSource = source; } //watch.Stop(); //MessageBox.Show(watch.ElapsedMilliseconds.ToString()); }
以上兩種方法在代碼量來看,第二種比較簡單,第一種在執行效率上相對第二種方法要高,原因很簡單,第一種每次處理的數據永遠都是每頁的數據,而第二種每次處理的數據是原有數據與現有數據的合集,隨著數據量越多,加載也就越慢,大家也可以試一下,當然如果大家有其它更好的方法也可以分享一下。 為了體現面向對象以及可復用性,我將上述方法變為擴展方法,完整代碼如下:
using System; using System.Collections.Generic; using System.Windows.Forms; using System.Data; namespace Zwj.Demo { public interface IAppendDataAble<out TControl> where TControl : Control { } public class DataGridView2 : DataGridView, IAppendDataAble<DataGridView> { } public static class AppendDataAbleControlExtension { public static void AppendData(this DataGridView grid, dynamic dataSource) { if (!(grid is IAppendDataAble<DataGridView>)) { throw new Exception("該DataGridView控件未實現IAppendDataAble<DataGridView>,無法使用該方法!"); } if (dataSource.GetType().IsValueType || dataSource == null) { grid.DataSource = null; return; } Type interfaceType=dataSource.GetType().GetInterface("System.Collections.IList", true); if (interfaceType!=null) { List<object> list = new List<object>(); list.AddRange(dataSource); AppendDataToGrid(grid, list); } else if (dataSource is DataTable) { AppendDataToGrid(grid, dataSource as DataTable); } } /// <summary> /// 附加數據到DataGridView(支持IList<T>類型的數據源) /// </summary> /// <param name="grid"></param> /// <param name="source"></param> private static void AppendDataToGrid(DataGridView grid, IList<object> source) { int rowCount = grid.Rows.Count; List<DataGridViewRow> rows = new List<DataGridViewRow>(); Type t = source[0].GetType(); int rowIndex = grid.Rows.Add(); var girdCells = grid.Rows[rowIndex].Cells; //Common.ShowProcessing("正在加載數據,請稍候...", Common.MainForm, (o) => //{ foreach (object item in source) { var row = new DataGridViewRow(); foreach (DataGridViewCell cell in girdCells) { var p = t.GetProperty(cell.OwningColumn.DataPropertyName); object pValue = p.GetValue(item, null); var newCell = (DataGridViewCell)cell.Clone(); newCell.Value = pValue; row.Cells.Add(newCell); } rows.Add(row); } //}); grid.Rows.RemoveAt(rowIndex); grid.Rows.AddRange(rows.ToArray()); } /// <summary> /// 附加數據到DataGridView(支持DataTable類型的數據源) /// </summary> /// <param name="grid"></param> /// <param name="table"></param> private static void AppendDataToGrid(DataGridView grid, DataTable table) { int rowCount = grid.Rows.Count; List<DataGridViewRow> rows = new List<DataGridViewRow>(); int rowIndex = grid.Rows.Add(); var girdCells = grid.Rows[rowIndex].Cells; //Common.ShowProcessing("正在加載數據,請稍候...", Common.MainForm, (o) => //{ foreach (DataRow r in table.Rows) { var row = new DataGridViewRow(); foreach (DataGridViewCell cell in girdCells) { object pValue = r[cell.OwningColumn.DataPropertyName]; var newCell = (DataGridViewCell)cell.Clone(); newCell.Value = pValue; row.Cells.Add(newCell); } rows.Add(row); } //}); grid.Rows.RemoveAt(rowIndex); grid.Rows.AddRange(rows.ToArray()); } } }
對代碼稍微說明一下,為了避免擴展方法被濫用,即不需要附加數據的普通DataGridView造成影響,我定義了一個接口來規范它:IAppendDataAble<out TControl>,當然這個接口適用於所有控件,然後在擴展方法時AppendData加判斷,如果實現了IAppendDataAble接口,則表明需要用到附加數據功能,就進行後面的處理,否則報錯。我這裡是基於DataGridView來擴展,大家也可以基於我定義的DataGridView2來擴展,這樣更方便。另外,我上面實現了針對兩種數據源類型進行了分別處理,以滿足大多數的情況。 方法種注釋掉的方法是我寫的顯示遮罩層的方法,如果大家需要,可以查看我的這篇博文:Winform應用程序實現通用遮罩層 使用方法如下: 1.添加DataGridView控件,然後將DataGridView類型更改為DataGridView2類型,當然如果大家不需要進行擴展約束,那就無需更改DataGridView控件類型。 2.設置DataGridView列,將列的DataPropertyName設置為需要綁定的數據字段名稱,這步很重要。 3.然後查詢數據並調用擴展方法: //dataGridView2Demo為DataGridView2類型 //dataSource為查詢到的數據 dataGridView2Demo.AppendData(dataSource); 為了提高擴展方法的執行效率,降低數據源類型判斷及轉換,我們也可以選擇將擴展方法直接分為兩個擴展方法,如下:
public static class ControlExtension { /// <summary> /// 附加數據到DataGridView(支持IList<T>類型的數據源) /// </summary> /// <typeparam name="T"></typeparam> /// <param name="grid"></param> /// <param name="source"></param> public static void AppendData<T>(this DataGridView grid, IList<T> source) where T : class { int rowCount = grid.Rows.Count; List<DataGridViewRow> rows = new List<DataGridViewRow>(); Type t = typeof(T); int rowIndex = grid.Rows.Add(); var girdCells = grid.Rows[rowIndex].Cells; Common.ShowProcessing("正在加載數據,請稍候...", Common.MainForm, (o) => { foreach (object item in source) { var row = new DataGridViewRow(); foreach (DataGridViewCell cell in girdCells) { var p = t.GetProperty(cell.OwningColumn.DataPropertyName); object pValue = p.GetValue(item, null); var newCell = (DataGridViewCell)cell.Clone(); newCell.Value = pValue; row.Cells.Add(newCell); } rows.Add(row); } }); grid.Rows.RemoveAt(rowIndex); grid.Rows.AddRange(rows.ToArray()); } /// <summary> /// 附加數據到DataGridView(支持DataTable類型的數據源) /// </summary> /// <param name="grid"></param> /// <param name="table"></param> public static void AppendData(this DataGridView grid, DataTable table) { int rowCount = grid.Rows.Count; List<DataGridViewRow> rows = new List<DataGridViewRow>(); int rowIndex = grid.Rows.Add(); var girdCells = grid.Rows[rowIndex].Cells; Common.ShowProcessing("正在加載數據,請稍候...", Common.MainForm, (o) => { foreach (DataRow r in table.Rows) { var row = new DataGridViewRow(); foreach (DataGridViewCell cell in girdCells) { object pValue = r[cell.OwningColumn.DataPropertyName]; var newCell = (DataGridViewCell)cell.Clone(); newCell.Value = pValue; row.Cells.Add(newCell); } rows.Add(row); } }); grid.Rows.RemoveAt(rowIndex); grid.Rows.AddRange(rows.ToArray()); } }