Solved

VB.Net DataGridView - RowsAdded Fired Twice

Posted on 2013-11-25
6
1,095 Views
Last Modified: 2013-12-02
Hopefully I am just missing something obvious here, but for the life of me I cannot find anything.

I have a form on which there is a DataGridView that is bound directly to rows in a DataSet. All of this has been set up using the designer. I do not touch the binding related properties anywhere in my code.

The DataGridView consists of bound fields and unbound fields, the latter of which I calculate and populate in the RowsAdded() event (e.g. there is an invisible data bound field that is a number of seconds, and an unbound visible field that is that value formatted into HH:MM:SS).

Anyhow, the issue I have is that the RowsAdded() event seems to be firing 4 times, the first time with e.RowIndex = 0 and e.RowCount = 1, the second with e.RowIndex = 1 and e.RowCount = 88 (which I was expecting), but it then fires a third and fourth time with exactly the same sequence of parameters.

I do a fair bit (not excessive) of formatting in the event (cell background colouring, value formatting etc), and the fact that it is all being executed twice is obviously going to unnecessarily slow my application down.

I have looked everywhere and cannot fathom out why it would be being fired twice - the binding is done in design and never changes, and the Fill() is only called the once.

Any clues as to what I might have done wrong ?

Thanks,
Matt
0
Comment
Question by:matthewgreen
  • 5
6 Comments
 

Author Comment

by:matthewgreen
ID: 39675166
A little more information. In total I have 3 DataGridView controls on the screen. Two are bound to data in the Designer, one is unbound and rows are programmatically loaded.

The two DGV's that are bound have the double firing of the RowsAdded() event, the one that I programmatically control fires just the once.

Matt.
0
 

Author Comment

by:matthewgreen
ID: 39675405
To add further to my confusion, I have a "Refresh" button on the frm that causes a data refresh for the grid. This calls the exact same code that is called at application startup (I have a RefreshGrid() routine that is called in Form_Load() and Button_Click() events). On the button click the RowsAdded() event fires just the twice.

What can possibly be the difference between Form_Load() calling the routine and Button_Click() ?? They are both running the same code.

I have checked and the Foam_Load() is only fired once, and there are only 3 references to the RefreshGrid() routine in the entire solution - 1 in Form_Load(), 1 in Button_Click, and the declaration.

It appears to be an issue with Data Binding to a grid at startup - everything seems to be done twice. Clearly if I take control myself (as I have done for one grid) and manually load the data then all is well, but if left to its own devices having bound to the data source at design time, it all seems to go wrong.

This is driving me crazy!!

Matt
0
 
LVL 40
ID: 39675836
In my opinion, the events in the DataGridView are a complete mess, so finding the cause of such a problem can be very hard.

I encountered the same one a few times, and ended up resorting to an inelegant solution, but it worked in my case.

I use a Static Boolean variable to make the event execute my code only once every 2 calls. A Static variable is a local variable that is not destroyed and keeps it value between calls.
Static flag As Boolean

If flag Then
    flag=False
    'Do nothing else
Else
    'Do your job
    flag=True
End If

Open in new window

0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 

Author Comment

by:matthewgreen
ID: 39675917
Hmm, not sure that solution would always be reliable. In my case the first two calls are needed, the next two calls are seemingly 100% redundant, and then every subsequent call (either from a button click or a timer) will be needed. It seems only that the initial loading causes an issue.

I could control that via the flag idea, but what makes me uncomfortable here is that documentation of the RowsAdded() event seems to imply that the number of calls may vary, hence the e.RowIndex and e.RowCount values being available. As such, any assumption that there will always be two calls to complete the load could come back to bite me.

It seems that if you control the loading of the rows from a data source to the DGV yourself (making the DGV completely unbound) the the events seem to fire okay (as evidenced by one of my grids that I control myself already).

I might try this tomorrow when back at work, to see if there is reasonable performance when I am programmatically doing all the work myself. Just seems a bit mad that the events of the DGV are so unpredictable on initial load.

Matt
0
 

Accepted Solution

by:
matthewgreen earned 0 total points
ID: 39680633
Okay, latest state of play.

I have removed all code out of any event related to DataBinding (DataBindingComplete, RowsAdded etc) and have left only event code that reacts to user actions. Anything related to the formatting of the grid, calculation and loading of unbound data is now under my control.

I have a new routine that does this, and the new sequence is:

JobData.ClearBeforeFill = True
JobData.Fill()
FormatJobData()

The FormatJobData() routine just cycles the rows in the grid:

For Each JobRow As DataGridViewRow In JobDataGrid.Rows
:
:
Next JobRow

.... and does the necessaries with each row.

All in all not much change in the coding, just the location and invocation. Result is the same, time to run reduced from 29 seconds when using the Grid Events to 1 second now.

Results speak for themselves. I am off to alter my other grid now, and am going to steer well clear of letting the Grid Events do much of anything in the future.

Matt
0
 

Author Closing Comment

by:matthewgreen
ID: 39689433
It was a rework undertaken myself that resulted in the issue being resolved, if you can call "avoiding the point of the issue" a solution. All I have done is avoid using the Grid Events that were causing the issue.
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Suggested Solutions

Flash (http://en.wikipedia.org/wiki/Adobe_Flash) has evolved over the years to where it has become a masterful tool for displaying content screen.  It has excellent layout placement, UI precision as well as rendering capabilities. This, along with t…
Summary Displaying images in RichTextBox is a common requirement with limited solutions available. Pasting through clipboard or embedding into RTF content only support static images.  This article describes how to insert Windows control objects int…
Sending a Secure fax is easy with eFax Corporate (http://www.enterprise.efax.com). First, Just open a new email message.  In the To field, type your recipient's fax number @efaxsend.com. You can even send a secure international fax — just include t…
When you create an app prototype with Adobe XD, you can insert system screens -- sharing or Control Center, for example -- with just a few clicks. This video shows you how. You can take the full course on Experts Exchange at http://bit.ly/XDcourse.

757 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

23 Experts available now in Live!

Get 1:1 Help Now