首页 新闻 会员 周边

DataGridView和BindingList异常

0
悬赏园豆:10 [待解决问题]

在winform应用里,有DataGridView,用BindingList 做数据源。

MotionList = new List<Motion>();
MotionBList = new BindingList<Motion>(MotionList);
DataGridViewMotion.DataSource = MotionBList;
DataGridViewMotion.RowHeadersVisible = false;
DataGridViewMotion.AllowUserToAddRows = false;
DataGridViewMotion.ReadOnly = true;

Where

public class Motion
{
    public string StartTime { get; set; }
    public string EndTime { get; set; }
    public string StartPos { get; set; }
    public string EndPos { get; set; }
}

MotionBList.Add() MotionBList.RemoveAt() 这两方法来更新DataGridViewMotion. 只有如下用法,都用SyncContext在UI线程执行了:

SyncContext = WindowsFormsSynchronizationContext.Current;

SyncContext.Post(new SendOrPostCallback((_) =>
{
    if (MotionBList.Count > 600)
    {
        for (int i = 0; i < 100; i++)
        {
             MotionBList.RemoveAt(0);
        }
    }
    MotionBList.Add(MakeMotion(...));
}), null);

private Motion MakeMotion(string a, string b)
{
    return new Motion() {StartPos = a, EndPos = b};
}

大部分时候都正常工作,但是 MotionBList.Add(MakeMotion(...))时有小概率报错, 报错信息如下:

Application_ThreadException System.ArgumentOutOfRangeException: 107 的值对于 indexStart无效, indexStart 必须小于等于 93.
在 System.Windows.Forms.DataGridViewRowCollection.GetPreviousRow(Int32 indexStart, DataGridViewElementStates includeFilter)
在 System.Windows.Forms.DataGridViewRowCollection.GetPreviousRow(Int32 indexStart, DataGridViewElementStates includeFilter, DataGridViewElementStates excludeFilter)
在 System.Windows.Forms.DataGridView.CorrectRowFrozenState(DataGridViewRow dataGridViewRow, DataGridViewElementStates rowState, Index32 anticiptedRowIndex)
在 System.Windows.Forms.DataGridView.OnInsertingRow(Int32 rowIndexInserted, DataGridViewRow dataGridViewRow, DataGridViewElementStates rowState, Point& newCurrentCell, Boolean firstInsertion, Int32 insertionCount, Boolean force)
在 System.Windows.Forms.DataGridViewRowCollection.InsertInternal(Int32 rowIndex, DataGridViewRow dataGridViewRow, Boolean force)
在 System.Windows.Forms.DataGridViewRowDataCollection.ProcessListChanged(ListChangedEventArgs e)
在 System.Windows.Forms.DataGridViewRowDataCollection.currencyManager_ListChanged(Object sender, ListChangedEventArgs e)
在 System.Windows.Forms.CurrencyManager.OnListChanged(ListChangedEventArgs e)
at System.Windows.Forms.CurrencyManager.List_ListChanged(Object sender, ListChangedEventArgs e)
在 System.ComponentModel.BindingList~1.OnListChanged(ListChangedEventArgs e)
在 System.ComponentModel.BindingList~1.FireListChanged(ListChangedType type, Int32 index)
在 System.ComponentModel.BindingList~1.InsertItem(Int32 index, T item)
在 System.Collections.ObjectModel.Collection~1.Add(T item)
在 MotionBList.Add(MakeMotion(...))

上面的异常是 Programe.cs 里的代码捕获到的

Application.ThreadException += Application_ThreadException;  //只捕获UI线程的错误
private static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
{
   MessageBox.Show($"Application_ThreadException {e.Exception}");
}
tossorrow的主页 tossorrow | 初学一级 | 园豆:16
提问于:2021-07-07 17:35

把异常捕获事件注释,看下实际在哪报错

拒绝访问 2年前
< >
分享
所有回答(2)
0

你搜一下在哪调用了这个方法吧:
GetPreviousRow

三述石 | 园豆:214 (菜鸟二级) | 2021-07-09 13:41

GetPreviousRow是System.Windows.Forms.dll里面的函数,是MotionBList.Add函数触发的。

支持(0) 反对(0) tossorrow | 园豆:16 (初学一级) | 2021-07-09 19:21
0

用同步的试试,如果同步的方法没问题,那可能是你代码其他地方有操作这个集合,导致下标索引在不同的地方同时被消耗了。

HelloLLLLL | 园豆:434 (菜鸟二级) | 2022-01-02 10:58
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册