Hi there
We using 13.1.20131.2040 of the UltraWinGrid in a VS 2010 .NET 4.0 C# WinForms app.
We are using the grids BeforeRowDeactivate event handler to perform validation and have noticed that the ClickCell event handler is never hit if we place a MessageBox in our validation within the BeforeRowDeactivate event handler.
Even when e.Cancel = false in the BeforeRowDeactivate event handler, if a MessageBox is used in that event handler then the ClickCell event handler is never hit but if we do NOT use a MessageBox then the ClickCell event handler is hit no problem.
What we are trying achieve is to validate/save in BeforeRowDeactivate, the user is prompted to save any unsaved data in that event handler, and if they do NOT wish to save to load child data for the next row in ClickCell
Is there a workaround to this?
Should I be using another event for validation or another event to load the data?
Sorry about not having a sample but our app is a pretty big beast and I have not as yet had a chance to create a sample to reproduce.
Regards
Geoff
Hi Geoff,
It's not uncommon for a MessageBox shown in certain grid events to interfere with the firing of other events, especialy mouse-related events. Showing a modal dialog takes focus away from the application so the mouse messages can get lost or be handled by the new dialog.
I'd recommend not showing a MessageBox inside of BeforeRowDeactivate, if you can. If you must do this, then try moving the MessageBox.Show call into a separate method and then using BeginInvoke to show it, instead of showing it from directly inside the event. That will create a delay so that the MessageBox shows after all of the event processing is complete.
void ultraGrid1_BeforeRowDeactivate(object sender, CancelEventArgs e) { UltraGrid grid = (UltraGrid)sender; grid.BeginInvoke(new MethodInvoker(this.ShowMessageBoxForBeforeRowDeactivate)); } private void ShowMessageBoxForBeforeRowDeactivate() { MessageBox.Show("Yoho"); }
Thanks Mike
Unfortunately I cannot really get around displaying a message box for the user to be prompted to save, disregard or remain on the current row when attempting to change rows.
Essentially our model is that if the user is navigating up/down the grid rows via keyboard we do NOT load the child data but as soon as the click on it we do load the child data. But when moving between rows if the user has changed and data then they are asked to Save or Reject the changes and move on OR cancel and remain on the row with the changed data.
The alternative of using BeginInvoke is also problematic in that we are using the ClickCell event to load child data for a row and when BeginInvoke is used it runs through to that ClickCancel event even if we set e.Cancel=true in the BeforeRowDeactivate event, obviously because of it's async design.
Can you tell me is there any publicly available event that fires prior to the BeforeRowDeactivate event (cancellable or otherwise)? I was thinking maybe I could test for row changes in that event and display messages in that event handler and then just use a flag to set the e.Cancel value in the BeforeRowDeactivate event.
Also is it possible to at all tell if in the BeforeRowActivate or AfterRowActivate event if the row was activated via a mouse click OR from a keystroke?
I'm not sure I am following you. You are using ClickCell to load the child data for the row, so I guess the scenario here is that the user is on a row and makes a change and then clicks on another row. So at this point BeforeRowDeactivate fires and you want to show a Messagebox which may potentially cancel the leaving of the row. Is that right?
So without the MessageBox, the BeforeRowDeactivate is firing before the ClickCell event? Is that correct?
If that's all correct, then I'm not sure another event that fires before BeforeRowDeactivate would help you. Because if there were such an event, you would end up loading the child data for the row that was clicked on event when the BeforeRowDeactivate was cancelled. If that's not a problem for you, then you could try using the MouseDown event. If MouseDown fires before BeforeRowDeactivate, then all you would have to do is figure out which cell was under the mouse (if any). And that's very easy to do:
HOWTO:UltraWinGrid Mouse Position and Cell Identification
Hi Mike
Thanks again for the reply.
I'm not sure I am following you. You are using ClickCell to load the child data for the row, so I guess the scenario here is that the user is on a row and makes a change and then clicks on another row. So at this point BeforeRowDeactivate fires and you want to show a Messagebox which may potentially cancel the leaving of the row. Is that right? YesSo without the MessageBox, the BeforeRowDeactivate is firing before the ClickCell event? Is that correct? With or without a MessageBox BeforeRowDeactivate always fires before the ClickCell but if you use and MessageBox AND do NOT cancel then the ClickCell event does NOT fire at all, the click event gets swallowed by the MessageBox. Alternatively when using BeginInvoke to run the MessageBox the code is run async, by the nature of BeginInvoke, so that the ClickCell event fires AFTER the BeforeRowDeactivate STARTS but BEFORE BeforeRowDeactivate completes i.e. before you get a chance to Cancel in BeforeRowDeactivate. Hope that makes sense!Thanks again
Okay, all of that is pretty much what I thought. Have you tried MouseDown, like I suggested? That's the only other event I can think of that might fire before BeforeRowDeactivate and allow you to do what you need.