您的位置:首页 > 编程语言 > C#

C# Winform Datagridview 排序 多线程操作数据 遇到的坑

2017-05-19 16:25 513 查看
先上代码:

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 控件。最长用的控件 就是Datagridvie
9ba5
w。
用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 变量。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐