I have a collection of business objects bound to a XamGrid. Both the collection and the objects within it implement the correct interfaces to notify bound controls of changes, and fire the appropriate events, and this mostly works OK. For example, I have some properties which are calculated from other properties which are user-editable, and these are updated correctly on edit.
However, I also have summaries on some of my columns, and the summaries are not updated when the data in those columns changes. I've read a few posts that suggest calling XamGrid.InvalidateData to update the summaries, and while this does work (i.e. the summaries are updated), it results in an exception which is caught by my global Application.ThreadException handler. The exception details are:
An exception of type 'System.NullReferenceException' occurred and was caught.-----------------------------------------------------------------------------Type : System.NullReferenceException, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089Message : Object reference not set to an instance of an object.Source : InfragisticsWPF4.Controls.Grids.XamGrid.v17.1Help link : Data : System.Collections.ListDictionaryInternalTargetSite : Void RemoveEditorFromControl()HResult : -2147467261Stack Trace : at Infragistics.Controls.Grids.CellControl.RemoveEditorFromControl() at Infragistics.Controls.Grids.Cell.ExitEditMode(Object newValue, Boolean editingCanceled, Boolean evaluateBindings) at Infragistics.Controls.Grids.ConditionalFormattingCell.ExitEditMode(Object newValue, Boolean editingCanceled, Boolean evaluateBindings) at Infragistics.Controls.Grids.XamGrid.ExitEditModeInternal(Boolean cancel, ExitEditModeBehavior exitEditModeBehavior) at Infragistics.Controls.Grids.XamGrid.SetActiveCell(CellBase cell, CellAlignment alignment, InvokeAction action, Boolean allowSelection, Boolean setFocus, Boolean scrollIntoView) at Infragistics.Controls.Grids.XamGrid.SetActiveCell(CellBase cell, CellAlignment alignment, InvokeAction action, Boolean allowSelection, Boolean scrollIntoView) at Infragistics.Controls.Grids.XamGrid.SetActiveCell(CellBase cell, CellAlignment alignment, InvokeAction action) at Infragistics.Controls.Grids.Cell.HandleKeyDown(Key key, Int32 platformKey) at Infragistics.Controls.Grids.XamGrid.XamGrid_KeyDown(Object sender, KeyEventArgs e) at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target) at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs) at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised) at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args) at System.Windows.UIElement.RaiseTrustedEvent(RoutedEventArgs args) at System.Windows.Input.InputManager.ProcessStagingArea() at System.Windows.Input.InputManager.ProcessInput(InputEventArgs input) at System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport) at System.Windows.Interop.HwndKeyboardInputProvider.ReportInput(IntPtr hwnd, InputMode mode, Int32 timestamp, RawKeyboardActions actions, Int32 scanCode, Boolean isExtendedKey, Boolean isSystemKey, Int32 virtualKey) at System.Windows.Interop.HwndKeyboardInputProvider.ProcessKeyAction(MSG& msg, Boolean& handled) at System.Windows.Interop.HwndSource.CriticalTranslateAccelerator(MSG& msg, ModifierKeys modifiers) at System.Windows.Interop.HwndSource.OnPreprocessMessage(Object param) at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs) at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
If I ignore this exception, I end up with an editor control containing the updated value in a different cell of the relevant grid column... There is a strange pattern here: if I edit the first row, the control appears in the last row, if I edit the second row, it appears in the second last row, and so on, until it crosses over in the middle - so if I edit the last row, it appears in the first row. This extra editor control can be made to disappear by clicking in the cell containing it, and then clicking a different cell, but the cell then loses its internal padding...
The same thing happens if I force a rebind by resetting the DataContext of the user control which hosts the XamGrid.
I do have a workaround for this: if I don't call XamGrid.InvalidateData directly from an event handler raised by the underlying PropertyChanged event on the business object, but instead use the event handler to start a System.Windows.Forms.Timer with an interval of 1ms and which calls XamGrid.InvalidateData in its Tick event handler, everything works fine. However, that's not exactly what I'd call a clean solution...
Is there a better way?
Hello Duncan,
Thank you for contacting Infragistics.
Automatic updates of summary values are not built-in for performance reasons.
Please provide a sample application that isolates the issue. Note, in general, I would avoid performing XamGrid.InvalidateData on an object not in view and rather handle an event on the XamGrid itself when the cells are updating such as CellExitEditMode, CellUpdating, RecoredUpdating otherwise you might run into some timing issues.
If don't want to handle any events you could try handling a Dispatcher.BeginInvoke and performing InvalidateData within the property changed.
eg.
Dispatcher.BeginInvoke((Action) (() => { context.EndSaveChanges(result); }));
Let me know if you have any questions.
Sincerely,
Michael Di FilippoAssociate Software DeveloperInfragistics, Inc.www.infragistics.com/support