Fixing flicker in a DataGridView?
-
I am using a DataGridView to display a List of objects that change frequently (at a rate of up to 4 times per second.) I am using a BindingSource as the DataSource for the DataGridView and on every datachange event I set the BindingSource's DataSource to the List of objects. This results in a bunch of flicker. I attempted to fix this using SuspendLayout and ResumeLayout, but haven't seen a difference. Any ideas?
Andrew Stampor wrote:
I am using a BindingSource as the DataSource for the DataGridView and on every datachange event I set the BindingSource's DataSource to the List of objects.
What event do you mean by "datachange event"? Unless you're getting an entirely different list object than you were previously bound to, why are you setting the BindingSource's DataSource multiple times? -- I've killed again, haven't I?
-
Andrew Stampor wrote:
I am using a BindingSource as the DataSource for the DataGridView and on every datachange event I set the BindingSource's DataSource to the List of objects.
What event do you mean by "datachange event"? Unless you're getting an entirely different list object than you were previously bound to, why are you setting the BindingSource's DataSource multiple times? -- I've killed again, haven't I?
Thanks for your reply. I've changed the way I am trying to do this, but am not getting an update like I would like. What I am now doing is maintaining a List<CSomeObject>. That List is assigned as the datasource for the DataGridView. What I am noticing, though, is that when I update a value in one of the CSomeObjects that is part of the List, the value doesn't change on the grid until I click on the grid. Do you know what I am missing?
-
Thanks for your reply. I've changed the way I am trying to do this, but am not getting an update like I would like. What I am now doing is maintaining a List<CSomeObject>. That List is assigned as the datasource for the DataGridView. What I am noticing, though, is that when I update a value in one of the CSomeObjects that is part of the List, the value doesn't change on the grid until I click on the grid. Do you know what I am missing?
Ahh, the List class implements IList, and not the IBindingList interface. IBindingList fires a ListChanged event that informs the BindingSource to which it is bound, and subsequently the DataGrid to which that BindingSource is bound, that it should update. IList fires no such event, so the BindingSource never knows that it should update itself. My solution to the same problem was to create a class that derives from System.Collections.CollectionBase and implements IBindingList, and use it in lieu of an IList-based List. -- I've killed again, haven't I?
-
Thanks for your reply. I've changed the way I am trying to do this, but am not getting an update like I would like. What I am now doing is maintaining a List<CSomeObject>. That List is assigned as the datasource for the DataGridView. What I am noticing, though, is that when I update a value in one of the CSomeObjects that is part of the List, the value doesn't change on the grid until I click on the grid. Do you know what I am missing?
As far as the flickering goes, i think you should just enable double buffering. Here'a an example for a data grid: public class myDataGridClass : DataGrid { public myDataGridClass() { this.SetStyle(ControlStyles.DoubleBuffer | ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint , true); this.UpdateStyles(); } } Then, instead of using a DataGrid object you would simply use a myDataGrid object that has the DoubleBuffer flag set to true.
-
Ahh, the List class implements IList, and not the IBindingList interface. IBindingList fires a ListChanged event that informs the BindingSource to which it is bound, and subsequently the DataGrid to which that BindingSource is bound, that it should update. IList fires no such event, so the BindingSource never knows that it should update itself. My solution to the same problem was to create a class that derives from System.Collections.CollectionBase and implements IBindingList, and use it in lieu of an IList-based List. -- I've killed again, haven't I?
Hmmm... would this refresh only the changed cells in the grid, or does it refresh the whole thing anyway?
-
Hmmm... would this refresh only the changed cells in the grid, or does it refresh the whole thing anyway?
If I'm not mistaken, I believe it refreshes the row containing the element that was changed. -- I've killed again, haven't I?
-
If I'm not mistaken, I believe it refreshes the row containing the element that was changed. -- I've killed again, haven't I?
OK... I've changed the List to a BindingList, but when I make changes to the Properties, it doesn't update on the DataGridView. Is there a way I can trigger that event?
-
OK... I've changed the List to a BindingList, but when I make changes to the Properties, it doesn't update on the DataGridView. Is there a way I can trigger that event?
There are probably a few ways to do it. My collection objects trigger the ListChanged event via a call to the collection class that contains them. -- I've killed again, haven't I?
-
There are probably a few ways to do it. My collection objects trigger the ListChanged event via a call to the collection class that contains them. -- I've killed again, haven't I?
Instead of creating my own implementation of the IBindingList interface, I used the BindingList class. When I was updating the properties of the objects in the list, it was not triggering the ListChanged event. When I looked at ListChanged in help, it mentioned that it will only be fired by items in the list that implement the INotifyPropertyChanged interface. I added INotifyPropertyChanged to my object class and had it trigger the PropertyChanged event when one of the properties I was interested in changed. This resolved both the issue with the grid not updating and the flickering issue I was having before. Thanks for all of your help. :-D You never mentioned the INotifyPropertyChanged interface, so if you haven't heard about it until now, I'd suggest giving it a look.
-
Instead of creating my own implementation of the IBindingList interface, I used the BindingList class. When I was updating the properties of the objects in the list, it was not triggering the ListChanged event. When I looked at ListChanged in help, it mentioned that it will only be fired by items in the list that implement the INotifyPropertyChanged interface. I added INotifyPropertyChanged to my object class and had it trigger the PropertyChanged event when one of the properties I was interested in changed. This resolved both the issue with the grid not updating and the flickering issue I was having before. Thanks for all of your help. :-D You never mentioned the INotifyPropertyChanged interface, so if you haven't heard about it until now, I'd suggest giving it a look.
Glad to be of help! I've never used INotifyPropertyChanged. It looks like that would get me the same effect as the manual way without having to register the collection class to the collected object. Learning is fun! :laugh: Thanks! -- I've killed again, haven't I?