Обновление DataGridView через поток при прокрутке - PullRequest
10 голосов
/ 22 сентября 2010

Я застрял в этой проблеме, и будет очень полезно, если кто-нибудь решит эту проблему для меня

Я пытаюсь сделать следующее:

1) Инициализировать объект DataTable в событии загрузки формы и назначить его представление по умолчанию для dagvresult типа datagridview

2) При нажатии кнопки запускается поток STA (на самом деле я работаю с WatIN IE, поэтому возникает необходимость в создании потока STA), который вызывает метод, который создает идентичный DataTable dt и datatable, созданный на шаге 1, а затем добавляет 300 строк для этого.

3) вызывает делегата, который объединяет этот dt с datatable и, таким образом, обновляет dgvresult

Вот фрагмент кода для только что описанных шагов:

static class Program
{
    /// <summary>
    /// The main entry point for the application.This method is made STAThread as I need to intialize WatIN IE in the form load of frmMain
    /// </summary>
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new frmMain());
    }
}

/// код домена

/// <summary>
/// Delegate which Binds updated Datatable to gridview 
/// </summary>
/// <param name="dt">The Datatable to be merged with main datatable</param>

delegate void Bind_DataTable_to_GridView_Delegate(DataTable dt);

private void bind_DataTable_to_GridView(DataTable dt)
{
    if (dgvResult.InvokeRequired)
    {
        Bind_DataTable_to_GridView_Delegate del = new Bind_DataTable_to_GridView_Delegate(bind_DataTable_to_GridView);
        dgvResult.Invoke(del, new object[] { dt });
    }
    else
    {
        datatable.Merge(dt);
        dgvResult.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;

        //Autosizes the gridview 
        foreach (DataGridViewColumn dgvcol in dgvResult.Columns)
        {
            dgvcol.SortMode = DataGridViewColumnSortMode.NotSortable;
        }
    }
}

WatiN.Core.IE ie;     

private void frmMain_Load(object sender, EventArgs e)
{
    //intialize WatIN IE
    ie = new IE(URLs.mainURL);

    //initialization of columns in datatable
    DataColumn datacolumn1 = new DataColumn("Words");

    //Adding of columns in datatable
    datatable.Columns.Add(datacolumn1);            

    //Making the datatable permanent
    datatable.AcceptChanges();

    //Assigning default view of datatble as dgvResult's datasource
    dgvResult.DataSource = datatable.DefaultView;

    foreach (DataGridViewColumn  dgvcol in dgvResult.Columns)
    {
        dgvcol.SortMode = DataGridViewColumnSortMode.NotSortable;
    }
}

private void btnGenerateWords_Click(object sender, EventArgs e)
{
    try
    {
        if (datatable.Rows.Count > 0)
        {
            //Initializes the GenerateWords Thread           
            GenerateWords = new Thread(GenW);

            //Sets the apartment state to Static
            GenerateWords.SetApartmentState(ApartmentState.STA);

            //Starts the GenerateWords Thread           
            GenerateWords.Start();
        }

    }
    catch(Exception ex)
    {
        throw;
    }
}

#region function of GenerateWords thread
/// <summary>
/// function of GenerateWords thread
/// </summary>

void GenW()
{
    DataColumn datacolumn1 = new DataColumn("Words");

    //Adding of columns in datatable
    DataTable dt = new DataTable();
    dt.Columns.Add(datacolumn1);

    //At this point datatable has say 20 rows
    for (int dtindex = 0; dtindex < datatable.Rows.Count; dtindex++)
    {
        /*Code Which adds successfully 300 fresh rows to dt*/

        //sends datasource of dgvresult as dt
        bind_DataTable_to_GridView(dt);
        dt.Clear();
    }
 }

Теперь проблема возникает, когда в datagridview у меня много строк (предположим, 1000)

Теперь, если в пользовательском интерфейсе я ничего не делаю с datagridview, этот код работает без ошибок.

Но если я продолжу прокручивать представление сетки данных при вызове метода связывания, приложение выдаст ошибку и просто завершит работу из-за невозможности обновить представление сетки данных, я полагаю (или, возможно, из-за сбоя при вызове представления данных)

Вот ошибка:

В вашем приложении произошло необработанное исключение. Ссылка на объект
не установлен для объекта.

System.NullReferenceException: Object reference not set to an instance of an object.<br>
  at System.Windows.Forms.DataGridViewTextBoxCell.PaintPrivate(Graphics

графика, прямоугольник clipBounds, прямоугольник cellBounds, Int32 rowIndex, DataGridViewElementStates cellState, Object formattedValue, String errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts, Boolean computeContentBounds, Boolean computeErrorIconBounds, Boolean paint)
в System.Windows.Forms.DataGridViewTextBoxCell.Paint (графическая графика, прямоугольник clipBounds, прямоугольник cellBounds, Int32 rowIndex, DataGridViewElementStates cellState, Значение объекта, Объект formattedValue, String errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
в System.Windows.Forms.DataGridViewCell.PaintWork (графическая графика, прямоугольник clipBounds, прямоугольник cellBounds, Int32 rowIndex, DataGridViewElementStates cellState, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
в System.Windows.Forms.DataGridViewRow.PaintCells (графическая графика, прямоугольник clipBounds, прямоугольник rowBounds, Int32 rowIndex, DataGridViewElementStates rowState, Boolean isFirstDisplayedRow, Boolean isLastVisibleRow, DataGridViewPaintParts paintParts)
в System.Windows.Forms.DataGridViewRow.Paint (графическая графика, прямоугольник clipBounds, прямоугольник rowBounds, Int32 rowIndex, DataGridViewElementStates rowState, Boolean isFirstDisplayedRow, Boolean isLastVisibleRow)
в System.Windows.Forms.DataGridView.PaintRows (Графика g, Rectangle boundingRect, Rectangle clipRect, Boolean singleHorizontalBorderAdded)
в System.Windows.Forms.DataGridView.PaintGrid (Графика g, прямоугольник gridBounds, прямоугольник clipRect, Boolean singleVerticalBorderAdded, логическое значение singleHor HorizontalBorderAdded)
в System.Windows.Forms.DataGridView.OnPaint (PaintEventArgs e)
в System.Windows.Forms.Control.PaintWithErrorHandling (PaintEventArgs e, Слой Int16, логическое значение disposeEventArgs)
at System.Windows.Forms.Control.WmPaint (Сообщение & m)
в System.Windows.Forms.Control.WndProc (сообщение & m)
в System.Windows.Forms.DataGridView.WndProc (Message & m)
в System.Windows.Forms.Control.ControlNativeWindow.OnMessage (Message & m)
в System.Windows.Forms.Control.ControlNativeWindow.WndProc (Message & m)
в System.Windows.Forms.NativeWindow.Callback (IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

Я проверил это через VS, Это выдает эту ошибку в Program.cs в этой строке: Application.Run(new frmMain());

Как обойти эту проблему?

...