We are using a XamDataGrid, and when the user enters edit mode we use a XamMultiColumnComboEditor to display a number of items which can be clicked, or the text can be entered in autocomplete form.
Under v15.1 this worked fine, but in v15.2 we are getting an exception if the Escape key is pressed when the combo editor is displayed: "Collection was modified; enumeration operation may not execute."
We're trying to get a small sample app that shows the problem, but it is happening on the XamMultiColumnComboEditor where we handle OnPreviewKeyDown and check if the pressed key is the Escape key. In that case we call ExecuteCommand(DataPresenterCommands.EndEditModeAndDiscardChanges) on the XamDataGrid to undo any changes and leave edit mode.
I'll try to get a sample as soon as possible, but by chance is there already a known issue which would explain this problem?
Hi Walter,
I haven't heard about this issue myself so a sample will definitely be helpful. One thing I'm curious about is how you are hooking up your XamMultiColumnComboEditor. Are you doing this in a CellValuePresenter style or are you using the TemplateField? What is your combo editor binding to? The callstack for the exception might be useful as well.
Here is a sample app we've created which demonstrates the problem.
The following code does it:
if (grid.ActiveRecord.IsSpecialRecord) grid.RecordManager.CommitAddRecord();
I am doing as you suggested and anticipating the upcoming service release. I have a question about handling these events when occurring in the New Record line. If I am using a standard text field, anything that will commit the cell will call RecordAdding and thus make the New Record line drop to the next line, as would be expected.
However when I handle the multi column combo editor events and call grid.ExecuteCommand(DataPresenterCommands.EndEditModeAndCommitRecord), no new row is added below and the current record remains as the New Record row.
How can I get the new record to move down?
Thanks for the sample. I was able to reproduce the issue. Turns out all I was missing in my own sample was setting the DisplayMemberPath. Once I set this I was able to reproduce the exception in my own sample.
The main reason behind the exception is that when the cell exits edit mode it is unloaded and removed from the visual tree so it loses it's DataContext. This sets the DisplayMemberPath to null which causes an iteration over the visible items in the dropdown. For some reason, in this iteration items are being removed and the exception occurs. When using a foreach you can't remove items from the list you are iterating over. It worked for you in 15.1 because you were probably using version 15.1.20151.2055 where this wasn't an issue. This issue was introduced in the latest SR that came out a couple of weeks ago. 15.2 also uses this code so that's why it seems like it broke in 15.2 but worked in 15.1. If you stayed with 15.1 and just updated to the latest SR you would see still see this issue.
Since I was able to reproduce the issue and have determined the issue to lay with the XamMultiColumnComboEditor I have asked our engineering staff to examine this further. I have logged a development issue and the ID for this is 208072. I have also created a private support case for you so that you may track the status of this dev issue. The case number is CAS-165467-N4N4V5 and you can view it here.
The only work around I could come up with was to manually handle all the grid interactions that would cause the cell to exit edit mode and first close the dropdown, then in a Dispatcher I would execute the appropriate datagrid command. For example, if I wanted to press the Tab key to move to the next cell I would do this in the preview keydown event:
if (e.Key == Key.Tab){ e.Handled = true; bCloseComboEditor = false; editor.IsDropDownOpen = false; Dispatcher.BeginInvoke(new Action(() => MyDataGrid.ExecuteCommand(DataPresenterCommands.CellNextByTab)), DispatcherPriority.Background);}
This works because closing the drop down causes the combo editors visible list to become empty therefore there is nothing to iterate over and cause the exception. This is also why I use a Dispatcher. This delays when the command is executed so that it gives the combo editor enough time to clear the visible list. You'll have to do this for most of the grid interactions that would normally force the cell to exit edit mode.