(This seems somewhat related to https://www.infragistics.com/community/forums/f/ultimate-ui-for-windows-forms/56907/infinite-loop-error-message-on-celldataerror.)
We have an UltraGrid with FilterUIType.FilterRow, and some columns that can raise data errors (in this case, a DateTime column). We also have a feature where, if you're inside the filter row, type in a filter, and hit return, the first matching row gets opened as a form.
Unfortunately, this combination seems to cause an infinite loop, something like:
1. the user types, say, '08/24' in a date field. That is, they omit the year.
2. then they hit 'return'.
3. this opens a form, causing the filter cell to lose focus, which causes…
4. a dialog to pop up saying "Value in the editor is not valid"
5. then you hit OK on it, but that once again loses focus on the filter cell, so the dialog pops up again
Now, I've found that I can use the CellDataError event to get notified of the error in the filter cell. But what I really want is for my code that opens a form to know in advance that there's a data error, and to just not proceed at all. I.e., to ask the entire filter row whether there's any cell whose current value isn't valid.
I see that there's a Grid.DisplayLayout.Rows.FilterRow.DataErrorInfoResolved.HasErrors, but it's false. It seems DataErrorInfo is only used when manually filled by me.
Can I explicitly do something like a hypothetical Grid.DisplayLayout.Rows.FilterRow.ValidateAll()?
I have been investigating into the behavior you are seeing in this case, and I believe you should continue using the CellDataError event in this case to get whether or not an error is occurring in the FilterRow. This event firing should be enough to avoid the infinite loop, as the event arguments of that event expose some properties that you can use to prevent the dialog from showing (e.RaiseErrorEvent = false), or allow you to revert the value (e.RestoreOriginalValue = true).
I am under the impression that perhaps you are showing your dialog on key-down though, and perhaps that is happening before these events actually fire, in which case, maybe using key-up would be a better option for you, as you should be able to store some information about an error message occurring in the time between key-down and key-up?
I’m not sure I personally really see a reason to try to validate the entirety of the FilterRow’s cells in this case, because a cell value occurring should lock the cursor in the cell until the error is actually resolved, and the CellDataError event is meant to fire in response to the cell value not being valid, so if it fires while the grid’s ActiveCell is a filter cell, you can conclude that there is an error with that filter-cell’s value.
Please let me know if you have any other questions or concerns on this matter.
Andrew Goldenbaum said: I believe you should continue using the CellDataError event in this case to get whether or not an error is occurring in the FilterRow. This event firing should be enough to avoid the infinite loop, as the event arguments of that event expose some properties that you can use to prevent the dialog from showing (e.RaiseErrorEvent = false)
I get that, but then I'd have to manually keep track of which cells have previously raised an error, and then use FilterCellValueChanged to reset that flag for the respective cell, no?
Anyway, that's all moot, because:
Andrew Goldenbaum said:I am under the impression that perhaps you are showing your dialog on key-down though
Yes! You're completely right. I changed that particular event handler to KeyUp (which makes more sense anyway), and the infinite loop no longer occurs. Instead, just like you said, the focus returns to the cell, and the user can either fix it or cancel the input with 'esc'.
So, thanks! That turned out to be an easy fix. :)