DataGridView CellEnter event fires multiple times

When working on a Windows Forms Application I had a DataGridView and I wanted to update some textboxes at the bottom of the form when the user selected a particular row/cell. I looked at the different DataGridView events available and decided the best option to cover users clicking on a cell and them navigating around the DataGridView using the up and down arrows was the CellEnter event.

Everything seemed to be working fine but I was occasionally getting some strange result or errors so I decided to spend some time debugging to try and identify the issue. What I found was even if I was not clicking on the DataGridView certain other actions caused the CellEnter event to fire also when I first clicked on an a row/cell after loading the form the event fired twice. This was extremely problematic in my case as I was doing some additional processing on a background worker thread so these miscellaneous events being fired resulted in unexpected results and the occasion exception as the background worker thread was already in the middle of processing another request.

Reading up on the CellEnter event it mentions that the event may occur twice if the DataGridView didn’t have input focus. Thinking about it this made sense and related to the issue I was having where the event was indeed firing twice. What must be happening is when a user clicks on a cell the focus must first be set on the DataGridView and when this happens it must act like it is selecting the first cell hence every time I was debugging the first time around the column and row indexed were both 0. I was able to get around this by adding the code below to the top of the CellEnter event. This way if the DataGridView wasn’t Focused I could exist the event without processing.

Code Snippet
  1. if (!DgvData.Focused)
  2.             {
  3.                 return;
  4.             }

 

This seemed to work but it meant when I loaded the DataGridView first time around the additional information at the bottom of my form was not filled in as technically the form still didn’t have input focus. I was able to get around this by manually setting the focus on the DataGridView after I assigned my data source. This would then trigger the CellEnter event where DgvData.Focused would now be true so it would continue and do the additional processing I wanted.

Code Snippet
  1. //binding causes the cell enter event to fire.
  2.                     DgvData.DataSource = calls;                    
  3.                     //show calls tab. This causes the cell enter event to fire as well.
  4.                     ShowTab(TpCallPlans);
  5.                     
  6.                     DgvData.Focus();

 

The other issue I was having was the CellEnter event was firing when I was not touching the DataGridView. In my form I had multiple tabs and the DataGridView was on the first one. I have several buttons on the form that show or hide the relevant tabs but what I noticed was that removing a tab from the TabControl also triggered the CellEnter event. The code below shows the function I was using to only show the appropriate tab and when stepping through the code line 11, actually removing the tab from the TabControl, caused the CellEnter event to fire. Obviously this was not what I was expecting and was leading to incorrect data on certain sections of the form. What I found was the same fixed I used above also corrected this issue as while the event still fired the DataGridView didn’t have input focus so it simply existed the method.

Code Snippet
  1. /// <summary>
  2.         /// Method to hide all tabs except the one supplied
  3.         /// </summary>
  4.         /// <param name="tpToShow">A TabPage object of the tab we want to show</param>
  5.         private void ShowTab(TabPage tpToShow)
  6.         {
  7.             foreach (TabPage tp in TbOptions.TabPages)
  8.             {
  9.                 if (!tp.Name.Equals(tpToShow.Name, StringComparison.CurrentCultureIgnoreCase))
  10.                 {
  11.                     TbOptions.TabPages.Remove(tp);
  12.                 }
  13.  
  14.                 if (TbOptions.TabPages.Count == 0)
  15.                 {
  16.                     TbOptions.TabPages.Add(tpToShow);
  17.                 }
  18.  
  19.             }
  20.         }

 

Hopefully this can help other people encountering the same issue as it took me a while to work out why this was happening and how to resolve it.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s

%d bloggers like this: