c#DatagridView控件(VirtualMode)和线程

时间:2022-05-20 14:46:14

I have a weird issue with the DataGridView control in virtual mode and threading. I use a Cache class to stored 2 pages of data. When I scroll down and I have to load a new page in cache, there is a little delay before data is display (it's ok). But, instead of having the next row displayed(199th,200th,201th), the control skip many rows (CellValueNeeded). By example, I cached 1 to 200 rows, when I scrolling at 199, I'm loading a page to 200 à 299. However, in the datagrid it's display the row 320.. instead of 300. (I kept the mouse button pressed 2-3 secondes, before releasing it). I notice I have the problem only when I load the cache in a particular thread. Does anyone have a idea how I can fix this?

我在虚拟模式和线程中的DataGridView控件有一个奇怪的问题。我使用Cache类来存储2页数据。当我向下滚动并且我必须在缓存中加载新页面时,在显示数据之前会有一点延迟(没关系)。但是,控件不会显示下一行(第199,第200,第201),而是跳过许多行(CellValueNeeded)。例如,我缓存了1到200行,当我在199滚动时,我正在将页面加载到200à299。但是,在数据网格中它显示行320而不是300.(我按住了鼠标按钮)在释放之前2-3次。我注意到只有在特定线程中加载缓存时才会出现问题。有谁知道如何解决这个问题?

    private void datagridView_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e)
    {           
        e.Value = m_rfiCache.RetrieveElement(e.RowIndex, e.ColumnIndex);            
    }        
    ....

    public DataTable SupplyPageOfData(int lowerPageBoundary, int rowsPerPage)
    {
        e : " + lowerPageBoundary);
        DataTable dt = new DataTable();

        if (m_useThreading) //THIS DOESN'T WORK WELL
        {                 
            Thread MulThread = new Thread(delegate()
            {
                dt = this.LoadData(lowerPageBoundary, rowsPerPage);
            });   

            MulThread.Start();

            MulThread.Join();
        }
        else //OK.
        {
            dt = this.LoadData(lowerPageBoundary, rowsPerPage);
        }

        return dt;
    }

P.S. : This is only a snippet, I used an external API to extract data from ODB. This API used thread to load data.

附: :这只是一个片段,我使用外部API从ODB中提取数据。此API使用线程加载数据。

2 个解决方案

#1


1  

Does anyone have a idea or I can fix this?

有没有人有想法或我可以解决这个问题?

You can load the data in a background thread, but you can't add it to your main DataTable in the background thread itself.

您可以在后台线程中加载数据,但不能在后台线程本身中将其添加到主DataTable中。

One potential approach would be to load the data as you're doing, but into a separate DataTable. You could then, on the UI thread, call DataSet.Merge to merge this data in with your bound data correctly (which will be reasonable fast).

一种可能的方法是在您正在执行时加载数据,但将其加载到单独的DataTable中。然后,您可以在UI线程上调用DataSet.Merge将此数据与正确的绑定数据合并(这将是合理的快速)。

#2


0  

Finally, I found the solution. When the tread is processing and the scroll down button is pressed, my event for scrolling aren't sent to the datagrid unless my thread is finished. So I received a bunch of calls for drawing cells and the index was wrong. To avoid this, I removed the vs scrollbar from the datagridview and added a VSscrollbar control. When I'm loading data in my thread, I set to false the enable property on my scrollbar. When the thread is completed, I enable the scrollbar. Is not the BEST solution, but at least, there is now row skipped.

最后,我找到了解决方案。当踏板处理并按下向下滚动按钮时,除非我的线程完成,否则我的滚动事件不会发送到数据网格。所以我收到了一堆绘制单元格的调用,索引错了。为了避免这种情况,我从datagridview中删除了vs滚动条并添加了一个VSscrollbar控件。当我在我的线程中加载数据时,我将滚动条上的启用属性设置为false。线程完成后,我启用滚动条。不是最好的解决方案,但至少现在已经跳过了行。

Note : Virtual Mode works very well if you don't load your data in a separate thread.

注意:如果不在单独的线程中加载数据,则虚拟模式可以很好地工作。

#1


1  

Does anyone have a idea or I can fix this?

有没有人有想法或我可以解决这个问题?

You can load the data in a background thread, but you can't add it to your main DataTable in the background thread itself.

您可以在后台线程中加载数据,但不能在后台线程本身中将其添加到主DataTable中。

One potential approach would be to load the data as you're doing, but into a separate DataTable. You could then, on the UI thread, call DataSet.Merge to merge this data in with your bound data correctly (which will be reasonable fast).

一种可能的方法是在您正在执行时加载数据,但将其加载到单独的DataTable中。然后,您可以在UI线程上调用DataSet.Merge将此数据与正确的绑定数据合并(这将是合理的快速)。

#2


0  

Finally, I found the solution. When the tread is processing and the scroll down button is pressed, my event for scrolling aren't sent to the datagrid unless my thread is finished. So I received a bunch of calls for drawing cells and the index was wrong. To avoid this, I removed the vs scrollbar from the datagridview and added a VSscrollbar control. When I'm loading data in my thread, I set to false the enable property on my scrollbar. When the thread is completed, I enable the scrollbar. Is not the BEST solution, but at least, there is now row skipped.

最后,我找到了解决方案。当踏板处理并按下向下滚动按钮时,除非我的线程完成,否则我的滚动事件不会发送到数据网格。所以我收到了一堆绘制单元格的调用,索引错了。为了避免这种情况,我从datagridview中删除了vs滚动条并添加了一个VSscrollbar控件。当我在我的线程中加载数据时,我将滚动条上的启用属性设置为false。线程完成后,我启用滚动条。不是最好的解决方案,但至少现在已经跳过了行。

Note : Virtual Mode works very well if you don't load your data in a separate thread.

注意:如果不在单独的线程中加载数据,则虚拟模式可以很好地工作。