先上代碼:
public class BindingCollection<T> : BindingList<T>
{
protected bool isSorted;
protected PropertyDescriptor sortProperty;
protected ListSortDirection sortDirection;
public ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
/// <summary>
/// 構造函數
/// </summary>
public BindingCollection()
: base()
{
}
public delegate void ApplySortCoreDel(PropertyDescriptor property, ListSortDirection direction);
/// <summary>
/// 自定義排序操作
/// </summary>
/// <param name="property"></param>
/// <param name="direction"></param>
protected override void ApplySortCore(PropertyDescriptor property, ListSortDirection direction)
{
List<T> items = this.Items as List<T>;
try
{
if (Items != null)
{
ObjectPropertyCompare<T> pc = new ObjectPropertyCompare<T>(property, direction);
items.Sort(pc);
isSorted = true;
}
else
{
isSorted = false;
}
sortProperty = property;
sortDirection = direction;
}
catch (Exception ex)
{
log.Error("ApplySortCore");
log.Error(ex);
}
}
public void ApplySort(PropertyDescriptor property, ListSortDirection direction)
{
ApplySortCore(property, direction);
}
/// <summary>
/// 擷取一個值,訓示清單是否已排序
/// </summary>
protected override bool IsSortedCore
{
get
{
return isSorted;
}
}
/// <summary>
/// 擷取一個值,訓示清單是否支援排序
/// </summary>
protected override bool SupportsSortingCore
{
get
{
return true;
}
}
/// <summary>
/// 擷取一個隻,指定類别排序方向
/// </summary>
protected override ListSortDirection SortDirectionCore
{
get
{
return sortDirection;
}
}
/// <summary>
/// 擷取排序屬性說明符
/// </summary>
protected override PropertyDescriptor SortPropertyCore
{
get
{
return sortProperty;
}
}
/// <summary>
/// 擷取一個隻,指定類别排序方向
/// </summary>
public ListSortDirection SortDirection
{
get
{
return sortDirection;
}
}
/// <summary>
/// 擷取排序屬性說明符
/// </summary>
public PropertyDescriptor SortProperty
{
get
{
return sortProperty;
}
}
/// <summary>
/// 移除預設實作的排序
/// </summary>
protected override void RemoveSortCore()
{
isSorted = false;
this.OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
}
}
public class BindingListInvoked<T> : BindingCollection<T>
{
public BindingListInvoked() { }
private static ISynchronizeInvoke _invoke;
public BindingListInvoked(ISynchronizeInvoke invoke) { _invoke = invoke; }
public BindingListInvoked(IList<T> items) { this.DataSource = items; }
public void SetInvoke(ISynchronizeInvoke invoke) { _invoke = invoke; }
delegate void ListChangedDelegate(ListChangedEventArgs e);
protected override void OnListChanged(ListChangedEventArgs e)
{
if ((_invoke != null) && (_invoke.InvokeRequired))
{
IAsyncResult ar = _invoke.BeginInvoke(new ListChangedDelegate(base.OnListChanged), new object[] { e });
}
else
{
base.OnListChanged(e);
}
}
public IList<T> DataSource
{
get
{
return this;
}
set
{
if (value != null)
{
this.ClearItems();
RaiseListChangedEvents = false;
foreach (T item in value)
{
this.Add(item);
}
isSorted = false;
sortProperty = null;
//sortDirection = ListSortDirection.;
RaiseListChangedEvents = true;
OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
}
}
}
}
}
以前公司 沒有用原生 C# winform 控件,但考慮到 打開頁面速度,決定用 原生的Winform 控件。最長用的控件 就是Datagridview。
用List<T> 綁定資料後不能排序,百度後,我寫了BindingCollection<T>
他們說 用了BindingCollection 就可以綁定一次 ,修改Add資料是不用重新綁定。
我還以為,回頭是岸了。沒有想到是苦海的開始:
因為Datagridview 一旦修改資料就會報 錯BiJie.DealForm.FrmDealBuy - System.IndexOutOfRangeException: 索引 4 沒有值
一大堆呀
後來才知道 BindingCollection 在Add 時會觸發一些 UI ,更新UI 要在主線程 操作。
而 我用了多線程。。哈哈。。
我又一次 高興了。可是我設定了 一個 主窗體 做為SetInvoke 的參數 賦給 一個靜态變量。
可是 錯誤 還是存在。。。。憤怒。。。
沒有辦法 調試吧 。。。
功夫不負有心人
原來 在C# 中 BindingCollection<int> 和BindingCollection<string> 是 兩個類 在其中定義的 static 變量 當然也不能通用,是不同的兩個變量。
哈哈 到此為止 這個問題 總算 解決了
BindingCollection<Entity1>.setInvoke(Form1);
BindingCollection<Entity2>.setInvoke(Form1);
BindingCollection<T>中 不同的T 都要 設定 他的static 變量。