I'm trying to update data I have in a datagridview (based on checks set by the user), without losing the selection (on which a calculation is made). This works for me, but is a lot slower than clearing the complete dgv, making a new datatable and binding it.
This is what I tried :
when the datagridview need to be completely updated (different amount of rows), I clear the datagridview, make a new datatable and bind it. This works nice and fast, but the selection is lost. It's no problem the selection is lost, because the data is completely new.
sometimes I only need to update the values in the datagridview (and I don't want to lose the selection). I tried to either update the values in the bound datatable (works) or the values in the datagridview directly (this also works). However, both are a lot slower than just making a whole new datagridview using the first method :-(
when updating the datagridview, I stop drawing the panel on which it is placed
all events that the datagridview fires are suspended
autoresize etc is off
Can anyone explain why updating the cellvalues is so much slower than redoing the whole thing?
Is there another way to do it without losing the selection? I could remember the selection and set it again, but then I lose the way/order cells and columns where selected.
I finally found where the big delay occured. I was completely focused on the DataGridView, but it turned out the delay happend in the DataTable that was bound to it.
In order to do it fast :
first set each row of the DataTable to BeginEdit, so changes are not acted upon. After updating the DataGridView, do not make your DataTable accept the changes, it will make you lose the selection in the DataGridView.
[code]
for (int Row = 0; Row < MyDataTable.Rows.Count; Row++) MyDataTable.Rows[Row].BeginEdit();
// do your changes in the DataGridView (not the DataTable) here
UpdateDataGridView();
// never accept the changes in the DataTable, it will lose the selection in the DataGridView. Problem is that the DataTable is never updated, but this is not a problem in my case.
//MyDataTable.AcceptChanges();
[/code]
Related
After adding a row to a DataGrid, I would like to update my DataGridView (with the input source of said DataGrid) using that new row. However when I use .Update() and .Refresh(), the whole of the grid gets re-drawn. When refreshing relatively quickly (around 4 times per second), this creates an unpleasing jolty effect. I would like to find a way to add my row to the DataGridView, without re-drawing the whole thing, therefore removing the DataGridView.
C# Winforms
I think what you are looking for is a data binding.
https://learn.microsoft.com/en-us/dotnet/desktop/winforms/controls/how-to-bind-data-to-the-windows-forms-datagridview-control?view=netframeworkdesktop-4.8
This means the DataGrid is bound to e.g. a DataTable.
I've encountered a performance issue with the C# DataGridView control, which appears to be the result of the unsharing of a large number of rows. The DataGridView is bound to a bindingsource, which is, in turn, bound to a dataview. I've gone through the laundry list of dos and don'ts from the MSDN info (not using rows.count() etc), but I just can't get it to play the game.
Even if I start with a brand new DataGridView control, on a fresh form, and bind it to a bindingsource that has a basic test table as its source, just showing the form seems to cause all of the displayed rows to become unshared. Then, every single row I select causes that row to become unshared. I'm wondering if I'm wasting my time trying to prevent this?
In my actual DataGridView control, it's necessary for me to have at least one column that is not visible, which contains ID values. It's also necessary for me to search all the values in this column for a matching ID. It would appear that, as soon as I attempt to iterate through the values to find a match, this is causing every single row to become unshared. Is there a way to do this that does not cause all the rows to become unshared as I search?
I have 2 computer: server and client,same winform app on both,same database.
I want to be able to update the datagridview on database change
So I made a ticker update every 4 seconds that refresh the datagridview datasource.
Few problems when the datasource is changing
First if a row was choose(dataGridView_RowHeaderMouseClick) inside the datagrid ,it lost focus.
seconed if I scroll down the datagridview,the scroll bar jump to the start.
Any Idea on how to do it right?
Thanks
Baaroz
You do not want to refresh the DataSource every 4 seconds without any conditions. As you say, there are several functionality issues that will be affected by this (such as losing focus on a row, that although could be solved by storing the row handle every time you focus into a row, shouldn't be something that you need to do), without mentioning the fact that if the tables you are loading are large there will be a performance issue caused by the constant reload.
You should either trigger a refresh every time the DataSource changes, or what Anthbs says, compare the data with your grid's DataSource and only refreshing if they are different.
Heres a couple of idea's to reduce the refresh issues.
To reduce the chance of this occuring you could do a comparison of the new data with the data in the grid only refresh if the data has changed.
You could store the selected index before you refresh the grid and set it back after you have refreshed.
I want to make a single event that will capture every change in the data in a DataGridView. The list of events is pretty long. I was thinking I could bind the DataGridView to a DataTable since it has less events and it gets notified whenever the user changes the data in the DataGridView. Since the amount of data is tiny (2 columns and about 5 rows) but the user should be able to add, remove and edit rows, it would be a lot simpler if I put all possible changes in a single event so every other class that needs it gets notified when anything changes in the DataGridView's data by handing a single event. I don't want to capture when the user is typing in a cell or when a row is resized or anything that won't be normally considered as representing a change in the data. That's also why I think using a binded DataTable is a good idea. So my question is, which set of events is the minimum I need to handle in order to capture every possible change in the data contained in a DataGridView or in a DataTable (preferably a DataTable I think)?
I would try to bind to the following DataTable events:
RowDeleted
RowChanged
Those should give you what you want - notification only in case you edit, delete or add a row.
I have a GridView who's DataSource is set to a DataTable. The DataTable is updated by some backend logic every few seconds, at which point a delegate is called to refresh GridView.
Currently I am simply resetting the DataSource, but that causes a problem - it interrupts any ongoing edits in the grid view and makes the selection 'jump' to the top-left cell.
The update logic basically creates a new (identical with regard to columns and rows) DataTable.
Is there any standard way to do it without any drawbacks? Is my only option updating the current DataSource row by row, inserting values programmatically?
Thanks!
You should use a BindingList or some data source that supports change notification.
I'm confused by many things in this question. If you're using a GridView, and not a DataGridView, then you're either using ASP.NET, WPF, or .NET 1.1. Which is it?
Next: you're creating a new DataTable entirely? Well of course the control's going to get reset when you reset the DataSource. It doesn't know that the schema of your new DataTable is the same as the one it's replacing. It's got to go through the columns and re-establish the bindings.
Also, of course it's losing the current row. The current row belongs to the old DataTable, not the new one.
If you want a bound control to retain its state when you update the underlying data source, update the underlying data source, don't replace it with a new one.
Do your updates happen on a background thread? I don't know if it will work in your scenario, but you could try this threaded binding list; see the example to see the worker merrily editing the grid.