I've found several posts here regarding the OPPOSITE of this (forcing the grid to reflect new changes to the datasource), but the problem I'm having is exactly the other way round.
I've bound a simple BindingList<> to the grid, it displays exactly as I would expect.
One of the columns is a bool value, so it's displayed as a checkbox.
What I need is for the datasource to be updated when I change the state of any of those checkboxes.
I can intercept the ValueChanged, or the CellChanged events, but when I evaluate the DataSource from those events, it hasn't yet been updated via databinding. it's always lagging behind.
Here's a small sampleJust create a form with an ultragrid called GRID
and paste this in.
private void Form_Load(object sender, EventArgs e) { var l = new BindingList<Entry>(); l.Add(new Entry() { Name = "Name1", Selected = true }); l.Add(new Entry() { Name = "Name2", Selected = false}); l.Add(new Entry() { Name = "Name3", Selected = false }); l.Add(new Entry() { Name = "Name4", Selected = true }); grid.SetDataBinding(l, ""); //var c = grid.DisplayLayout.Bands[0].Columns[nameof(Entry.Selected)]; //c.Editor.ValueChanged += (s, a) => { WriteEntries(); }; //grid.CellChange += (s, a) => { WriteEntries(); } ; grid.AfterCellUpdate += (s, a) => { WriteEntries(); }; } private void WriteEntries() { var l = (BindingList<Entry>)grid.DataSource; var b = string.Join(",", l.Where(i => i.Selected).Select(i => i.Name)); System.Diagnostics.Debug.WriteLine($"Selected: " + b); } public class Entry { public string Name { get; set; } public bool Selected { get; set; } }
You can see the "WriteEntries" function simply evaluates the items in the BindingList and outputs the list of those rows that are checked.
When I run this, the output list is always missing the state of the last element that was toggled.
I'm guessing this is because within the given event, the databinding manager hasn't yet bee triggered to push the change to the grid back into the datasource.
But I'm at a loss as to how to manually perform that update.
I know there are other ways to accomplish this (for instance, avoid databinding and just query the state of the column of checks directly), but I'm looking for a solution using databinding if at all possible.
Hello Darin,
The reason why this is happening is because the cell where the checkbox is placed is still in edit mode. For example, if you place a breakpoint inside the AfterCellUpdate event it will only trigger when the user clicks on different cell or presses tab, meaning that the cell updates its value only when it exits edit mode.
What I can suggest you, in order to achieve the behavior you desire, is using the CellChange event instead. Inside its handler the PerformAction method should be called to exit edit mode on the grid and then the WriteEntries method should be called. What it would do is immediately when the user checks/unchecks the checkbox the cell will exit edit mode and the WriteEntries will be performed right after it. I also recommend you to use an if statement to check whether the cell belongs to the "Selected" column, otherwise the logic would be performed every time the user tries to modify a cell on the grid.
The code for it should be similar to this:
private void UltraGrid1_CellChange(object sender, Infragistics.Win.UltraWinGrid.CellEventArgs e) { if (e.Cell.Column.Key.Equals("Selected")) { this.ultraGrid1.PerformAction(Infragistics.Win.UltraWinGrid.UltraGridAction.ExitEditMode); WriteEntries(); } }
Please let me know if you have any questions.
Regards, Ivan Kitanov
Hi Ivan,
Thanks for the quick reply but unfortunately, that doesn't seem to work.
Here's what I tried
grid.UpdateMode = Infragistics.Win.UltraWinGrid.UpdateMode.OnCellChange; <---- tried with and without this grid.SetDataBinding(l, ""); grid.CellChange += (s, a) => { if (a.Cell.Column.Key == "Selected") { grid.PerformAction(Infragistics.Win.UltraWinGrid.UltraGridAction.ExitEditMode); WriteEntries(); } } ;Exact same behavior as before. It sure +sounded+ like a solution though.Still scratching my head....
Hey Mike
"But think about a DateTime cell"
Exactly right. Same with textboxes, really, most other editor types. Checkboxes (and I suppose radio buttons and related) would operate differently in this scenario which is what I'm encountering.
I think you're on the right track with the "is the event even firing"According to the online docs CellChange is "Supposed to fire when the content of the cell is modified", but that doesn't appear to be happening.If I hook the event like this
grid.CellChange += (s, a) => { System.Diagnostics.Debug.WriteLine($"CellChanged: " + a.Cell.Column.Key); };
I get nothing if I simply click the check in a single cell on or off. ONLY if I click to a different cell, does the event fire.
So it does look like the first question is, "What event can I hook to trigger on the change of a checkboxes value in a checkbox column.
I tried col.Editor.ValueChanged event, but it's behaving the same as CellChanged event
Darin
Hello Darin,I am attaching a sample that demonstrates what I have mentioned above. On my side everything works as expected and I am able to see the correct output of the WriteEntries() method. I have also included the suggestion that Mike gave about including e.Cell.Row.Update() after performing exit edit mode.
Could you test it on your side and let us know if you are observing the same behavior?Regards,IvanGridBindinglIstDSLagging.zip
Ah. Looks like this must be a bug that was fixed between the 1905 version and the 21.1 version.
I pulled your project and once I corrected it to use the version of grid we have, it fails in the same way I'm seeing.
That's not good. Upgrading controls is a pretty huge deal around here (not the $$ just the time)..
At least we know it's a prob that has been fixed. Now It seems, I need to start looking for workarounds.
Workaround:
private void UltraGrid1_CellChange(object sender, Infragistics.Win.UltraWinGrid.CellEventArgs e) { if (e.Cell.Column.Key.Equals("Selected")) { //this.ultraGrid1.PerformAction(Infragistics.Win.UltraWinGrid.UltraGridAction.ExitEditMode); //e.Cell.Row.Update(); var entry = e.Cell.Row.ListObject as Entry; if (null != entry) entry.Selected = bool.Parse(e.Cell.Text); WriteEntries(); } }
Ok. it's not a bug, it's some issue with my environment. I reset, and reloaded the sample that Ivan sent, reset it to use the 1902 Ultragrid and it DOES work exactly like I'm wanting. but the same sample loaded into my actual project solution fails like I'd mentioned. So. Thank you guys for the help. It does actually require the e.Cell.Row.Update() as Mike suggested, but that does correctly cause the bound datasource to get updated as you click the checkboxes.Now, I just have to resolve whatever the issue is with my specific environment.