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