I am working on a page with two tables: one to show all the items, and one to show only the selected items. An item can added to/removed from the selected list by a checkbox in either table that is bound to a boolean in the view models. The view models notify other entities in the page that an item has been selected or deselected by way of a delegate that is passed in on construction of the view model:
public bool ItemViewModel.Selected { get { return this.selected; } set { if (this.itemSelectedChangedHandler != null && value != this.selected) { this.selected = value; this.itemSelectedChangedHandler(this.item, this.selected); } } }
When an item is selected/deselected, the selected list will update by hiding non-selected items and showing selected items. It will also call a method to set the selected value of the view model without invoking the itemSelectedChangedHandler:
private void PageViewModel.UpdateSelectedItemsTable() { foreach (var row in this.selectedItemsTable.Rows) { var itemViewModel = row.ListObject as ItemViewModel;
if (this.dataModule.SelectedItems.Contains(itemViewModel.Item)) { itemViewModel.Select(true); itemViewModel.UpdateChildren(); row.ExpandAll(); row.Hidden = false; } else { itemViewModel.Select(false); row.CollapseAll(); row.Hidden = true; } }
}
public void ItemViewModel.Select(bool selected) { if (this.selected != selected) { this.selected = selected; this.OnPropertyChanged(nameof(this.Selected)); } }
I can successfully select and deselect items from the table of all items (which has a different view model but ends up calling the same UpdateSelectedItemsTable), however, when I try to deselect an item from the selected table, I can deselect the first item, but subsequent items will not enter into their set accessors when I click their checkbox. To make debugging even more confusing, if I have a breakpoint on the set accessor from the beginning, before I select or deselect any items, I can successfully deselect all items by clicking their checkbox in the selected items table. I have no idea why the same code would have different outcomes when I step through it and when I don't.
Any thoughts or suggestions would be appreciated at this point!
Thank you!
Tanner Stevenson said:How would I do that? Right now the ultragrid is creating a checkbox column automatically because it is bound to a boolean in the view model.
Oh, sorry, I got lost for a minute there thought these were standalone controls.
If this is in a grid, then I wonder if maybe you have code in the InitializeRow which is setting the value of the CheckBox cell under some conditions and maybe it's triggering when you are clicking the checkboxes and immediately setting them back to their original values. That's a common cause of a problem like this where the value appears to just refuse to change.
Do you have code in InitializeRow? If so, then try returning from the event immediately without executing any of the code and see if that makes the problem go away.
Of course, if you are doing your validation in there and that's what's causing it, then that won't really tell us much.
How would I do that? Right now the ultragrid is creating a checkbox column automatically because it is bound to a boolean in the view model.
Also... one other thing you might try, just as a test, it so Find/Replace the UltraCheckEditor with a regular CheckBox control and see if the problem still occurs. That, at least, will isolate the problem and tell you if it's the UltraCheckEditor or something in your code.
Hi Tanner,
I'm not sure I am following all of that. But if you have a singleton class that is handling validation, then is it possible that when one checkbox is unchecked, it somehow causes the other checkbox's values to change, which causes all of them to validate, which then causes a cascading effect where they are all just stuck in a loop of validations?
Hi Mike,
So the strange thing about this behavior is the item that is unchecked can continue to be checked and unchecked. It is only the other items that can no longer be unchecked.
I have been able to identify the source of the problem, but I do not yet understand why it causes the issue. I am working on getting the basic example to reproduce the error, but it is a slow grind as I cannot use any of our proprietary libraries. In a nutshell, the problem arises when I call a validation routine after an item is selected or deselected. The validation routine resides in a singleton validator class and triggers an event that all pages subscribe to, notifying them when they need to validate. Each page will then handle the event and return whether or not the information in them is valid to the validator class. When the page in question responds to the event, it iterates through the row view models and updates a flag variable to display to the user if there is an error in the row. When this flag variable is changed, it will call OnPropertyChanged to update the view. If this method is called directly when an item is selected/deselected, without going through the event handler for the validator class, everything works fine. But as soon as the select/deselect calls the validator class' validation method, the checkboxes freeze. I have stepped through all of the subscribers to the validation event, and none of them throw an error, so it seems like the issue has something to do with the time/overhead involved with the validation of all pages in addition to updating the view models' flagged properties and calling OnPropertyChanged, including the view model who initiated this whole sequence.
Hopefully you were able to follow that. If not, I will continue to work on reproducing the issue.