Hi,
I have a problem whith the ultraGrid.I am editing a string field, and while still editing, I click outside the grid such as I gice the focus to another component.The gridLostFocus event is not raised. (If I am editing in an UltraNumericEditor it works fine).Is that a know problem, or do I do something wrong ?
Thanks
Anne-Lise
Hi Anne-Lise,
What component outside the grid are you clicking on? Not all components take focus. If you click on a toolbar button, for example, the grid will not lose focus.
In any case, I would strongly recommend that you do not use LostFocus or GotFocus events on any control. These events are tied directly to Windows messages and they will give you all sorts of unexpected results. Microsoft's documentation advises against using them in DotNet, also. You should use Enter and Leave, instead.
It occurs with different sort of components which take focus:
If I use a ultraNumericEditor to edit in my cell it works (Grid lostFocus is correctly sent), but if I use default behavior to edit in cell or a ultraTextEditor it does not works (Grid lostFocus is not sent when another component take the focus).
Tanner Stevenson said:an UltraTextEditor is built in an entirely different way than a UltraNumericEditor or a UltraFormattedTextEditor
Yes, that is correct - the UltraTextEditor displays a TextBox control over the cell and the other editors do not. Since the focus is on the TextBox and not on the grid, the grid doesn' lose focus, becuase it didn't HAVE focus. This is why you really should use the LostFocus or GotFocus events in Windows forms. These events are tied to Windows messages and don't work well if you have controls that contain other controls. This is one of the reasons why the Enter and Leave events exist.
Tanner Stevenson said:So since all of these issues came to light simply because I wanted to save character literals to my data objects, one way to solve my problem in a "nice" way would be to simply allow character literals through the UltraFormattedTextEditor.
I don't understand what you mean by "save character literals". What's a "character literal?"
Tanner Stevenson said:The event that happens because of the button click is the business logic, so the button's command is bound to a command in the view model. The view does not subscribe to any button click events.
Well, that's a choice you have made for your application. It doesn't have to be that way, and if your UI controls require you to do something to the UI before the business logic is called, then you would need to write code to change that.
Mike Saltzman said:This is why you really should use the LostFocus or GotFocus events in Windows forms. These events are tied to Windows messages and don't work well if you have controls that contain other controls. This is one of the reasons why the Enter and Leave events exist.
I assume you meant "you really shouldn't use" but regardless, I have tried subscribing to the Enter and Leave events and they never get thrown. In fact, none of the events of the UltraTextEditor get thrown. I have tried subscribing to BeforeEnterEditMode, BeforeExitEditMode, GotFocus, LostFocus, Enter, and Leave and none of them get thrown.
Mike Saltzman said:I don't understand what you mean by "save character literals". What's a "character literal?"
What I mean is if I type '&', I want that character to be saved in my data source instead of '&'.
Mike Saltzman said:Well, that's a choice you have made for your application. It doesn't have to be that way, and if your UI controls require you to do something to the UI before the business logic is called, then you would need to write code to change that.
Well what I should be able to do is write code in my custom ultragrid so that it can apply to every instance where I use an ultragrid, where if it is in edit mode when i click anything outside of it, the data source gets committed, regardless of which editor I use in the current cell.
The Leave event of the ultragrid also never gets thrown.
Tanner Stevenson said:The Leave event of the ultragrid also never gets thrown.
Well.. the Leave event will not fire unless focus leaves the grid. This will not happen in this case because you are clicking on a toolbar button and the toolbar button does not take focus. It would fire if you clicked on a regular button or some other control that takes focus.
Tanner Stevenson said:Or how I could commit character literals to my data objects?
I still do not understand what you are asking. What is a "character literal?" The grid stores whatever the Value property of the cell is.
Mike Saltzman said:Well.. the Leave event will not fire unless focus leaves the grid. This will not happen in this case because you are clicking on a toolbar button and the toolbar button does not take focus. It would fire if you clicked on a regular button or some other control that takes focus.
I've already told you that the button does take focus, or else I wouldn't see the Leave event be thrown when I have an UltraFormattedTextEditor in the cell, so that explanation does not apply. Also I'm still confused as to why any of the events of an UltraTextEditor do not get thrown such as Before/AfterEnterEditMode or GotFocus. And above all, why would the behavior of the grid be different based on the editor component in the selected cell? Shouldn't the grid be agnostic to the editor component? This is seriously one of the most frustrating aspects of this grid. The functionality details are so swept under the rug, no one seems to know why the table behaves in the way it does.
Mike Saltzman said:I still do not understand what you are asking. What is a "character literal?" The grid stores whatever the Value property of the cell is.
What I mean is if I type '&', I want that character to be saved in my data source instead of '&'. I have figured out a hack way to do this, so this discussion is now probably moot. Using an UltraFormattedTextEditor I subscribed to the BeforeCellUpdate and did the following if anyone else has a similar issue:
if (e.Cell.Column.DataType == typeof(string)) { var columnProperty = e.Cell.Row.ListObject.GetType().GetProperty(e.Cell.Column.Key);
if (columnProperty != null) { columnProperty.SetValue(e.Cell.Row.ListObject, e.Cell.Text); e.Cancel = true; } }
Thanks for trying.
I think that's correct, yes. It would certainly explain all of the behaviors you are getting.
Okay so the real confusion then is the word "focus" and even though a form of "focus" is placed on the button, it is not the type that is necessary to throw the Leave event. Would you agree?
Well, thank you for your time and help.
Hi Tanner,
My guess is (and I say guess because we're really talking about the DotNet Framework here and not the Infragistics controls any more) that since the Toolbar is a separate windows and the GotFocus and LostFocus are tied to windows messages that as far as Windows is concerned, the toolbar gets focus. But that's not the same kind of focus we're talking about when we talk about focus in DotNet. Which is why, once again, Microsoft's documentation recommends using Leave and Enter and not using GotFocus and LostFocus.
If the toolbar button does not gain focus, why then is the GotFocus event thrown when the toolbar button is clicked?
Tanner Stevenson said: I realized that the Leave event doesn't get thrown with either editor, but the grid's lost focus event does get thrown with the UltraFormattedTextEditor.
Okay... well, that makes perfect sense and it's one of the main reasons why using the LostFocus event is NOT a good idea. LostFocus is tied to the Windows messages. When a grid cell with a FormattedTextEditor is in edit mode, the grid has focus. Therefore, when you click on some other control, the grid loses focus.
But, if the grid does not have focus, because it contains a child control (like a TextBox) which is what happens when a regular text cell has focus, the event will not fire. It doesn't fire because the grid didn't lose focus, because the grid didn't HAVE focus. The TextBox did.
If you really want to jump through these kinds of hoops to make this work, then you could handle the grid's ControlAdded event and hook the LostFocus event of the child controls that are added to the grid. You would, of course, also want to unhook the event in ControlRemoved. But this isn't going to work very well for that you want, either, because the TextBox will lose focus when you leave one grid cell and move to another one, for example. In such a case, the TextBox loses focus and the grid gets focus.
This complexity with child control is why it's not a good idea to rely on GotFocus and LostFocus in DotNet for WinForms. The Enter and Leave events take care of all the child controls for you so you don't have to worry about it. Of course, they only fire when another control actually takes focus, and as we've already covered, the Toolbar buttons don't.
So after all this, we are basically back where we started. The simplest and easiest way for you to solve this problem is to simply call UpdateData on the grid in the click event of your toolbar button.