Click here to Skip to main content
15,881,248 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I dont know how to adjustment question format..
I am working on WinForm application, there is some DataGridView using a BindingList as datasource.
C#
MotionList = new List<motion>();
MotionBList = new BindingList<motion>(MotionList);
DataGridViewMotion.DataSource = MotionBList;
DataGridViewMotion.RowHeadersVisible = false;
DataGridViewMotion.AllowUserToAddRows = false;
DataGridViewMotion.AllowUserToResizeRows = false;
DataGridViewMotion.EnableHeadersVisualStyles = false;
DataGridViewMotion.ReadOnly = true;
for (int i = 0; i < dataGridViewMotion.Columns.Count; i++)
{
    dataGridViewMotion.Columns[i].SortMode = DataGridViewColumnSortMode.NotSortable;
}


Where
C#
public class Motion
{
    public string StartPos { get; set; }
    public string EndPos { get; set; }
}

Then I use Method like MotionBList.Add() MotionBList.RemoveAt() to update DataGridViewMotion. It Works normally most of the time. methods was used them only this way, and executed only in UI Thread.
C#
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};
}

it has a small probability of exception in line MotionBList.Add(MakeMotion(...)), messages is as follows:
Application_ThreadException System.ArgumentOutOfRangeException The value of 107 is invalid for indexStart, indexStart must be less than or equal to 93. <br>
at System.Windows.Forms.DataGridViewRowCollection.GetPreviousRow(Int32 indexStart, DataGridViewElementStates includeFilter)<br>
at System.Windows.Forms.DataGridViewRowCollection.GetPreviousRow(Int32 indexStart, DataGridViewElementStates includeFilter, DataGridViewElementStates excludeFilter)<br>
at System.Windows.Forms.DataGridView.CorrectRowFrozenState(DataGridViewRow dataGridViewRow, DataGridViewElementStates rowState, Index32 anticiptedRowIndex)<br>
at System.Windows.Forms.DataGridView.OnInsertingRow(Int32 rowIndexInserted, DataGridViewRow dataGridViewRow, DataGridViewElementStates rowState, Point& newCurrentCell, Boolean firstInsertion, Int32 insertionCount, Boolean force)<br>
at System.Windows.Forms.DataGridViewRowCollection.InsertInternal(Int32 rowIndex, DataGridViewRow dataGridViewRow, Boolean force)<br>
at System.Windows.Forms.DataGridViewRowDataCollection.ProcessListChanged(ListChangedEventArgs e)<br>
at System.Windows.Forms.DataGridViewRowDataCollection.currencyManager_ListChanged(Object sender, ListChangedEventArgs e)<br>
at System.Windows.Forms.CurrencyManager.OnListChanged(ListChangedEventArgs e)<br>
at System.Windows.Forms.CurrencyManager.List_ListChanged(Object sender, ListChangedEventArgs e)<br>
at System.ComponentModel.BindingList~1.OnListChanged(ListChangedEventArgs e)<br>
at System.ComponentModel.BindingList~1.FireListChanged(ListChangedType type, Int32 index)<br>
at System.ComponentModel.BindingList~1.InsertItem(Int32 index, T item)<br>
at System.Collections.ObjectModel.Collection~1.Add(T item)<br>
at MotionBList.Add(MakeMotion(...))


And red cross appears on many other controls, Above exception was catched by code in Programe.cs
C#
Application.ThreadException += Application_ThreadException;
private static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
{
   MessageBox.Show($"Application_ThreadException {e.Exception}");
}


What I have tried:

I have replaced MotionBList.Add(MakeMotion(...)) with var temp = MotionBList.AddNew(); MotionBList[MotionBList.IndexOf(temp)] = MakeMotion(...);
Posted
Updated 9-Jul-21 19:46pm
v16

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900