Sometimes the user gets an NullReferenceException when he is grouping a field in the xamdatagrid. There are two cases:
-after dragging a field to the groupbyarea
-after dragging a field from the groupbyarea a littie to the right and letting go. Effectivly doing nothing. You also have to, after dragging/after letting go of the left mouse button, quickly switch to another application (alt-tab or by clicking).
We have a custom control that derives from XamDataGrid. But I also could reproduce the bug with a default Xamdatagrid described here:
http://help.infragistics.com/Doc/WPF/2012.2/CLR4.0/?page=xamDataGrid.html
We use version 12.2.
After debugging I found the following:
The starting point is OnMouseLeftButtonUp. This function calls fieldDragManager.OnDragEnd. Than OnDragEndHelper. One of the things that happens here is the cleaning up of the Drag and Drop indicators.
The problem is that the closing of the Dropindicator sometimes causes that the OnLostMouseCapture of the xamdatagrid fires. And in the OnLostMouseCapture the fieldDragManager.OnDragEnd is called again. It seems to me that this is not intended behavior.
It's hard to reproduce, only happens one in ten times. If you debug and set breakpoints in thse functions than it happens easier because than the OnLostMouseCapture is trigged easier because the focus shifts to Visual Studio, but that's ofcourse a little cheating.
What happens in code chronologically:
protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
{
if (this._fieldDragManager != null)
this._fieldDragManager.OnDragEnd(e, false);
base.ReleaseMouseCapture();
}
base.OnMouseLeftButtonUp(e);
private void OnDragEndHelper(MouseEventArgs mouseEventArgs, bool cancel) { if (this._scrollTimer != null) { DispatcherTimer timer = this._scrollTimer; this._scrollTimer = null; timer.Stop(); } LabelPresenter presenter = this._dragElement as LabelPresenter; if (presenter != null) { presenter.IsDragSource = false; } if (!cancel) { PointInfo mouseLoc = new PointInfo(this, mouseEventArgs.GetPosition(this._dataPresenter), this._dataPresenter); this.DragHelper(mouseLoc, true); } Mouse.OverrideCursor = null; this.HideDragIndicator(); this.HideDropIndicator(); if (this._dragIndicatorWindow != null) { this._dragIndicatorWindow.Dispose(); this._dragIndicatorWindow = null; } if (this._dropIndicatorWindow != null) { this._dropIndicatorWindow.Dispose(); this._dropIndicatorWindow = null; } }
private void HideDropIndicator() { if (this._dropIndicatorWindow != null) { DropIndicator dropIndicator = DropInfo.GetDropIndicator(this._dropIndicatorWindow); if (dropIndicator != null) { dropIndicator.DropLocation = 0; } //the closing of this window sometimes causes that OnLostMouseCapture is fired. this._dropIndicatorWindow.Close(); this._dropIndicatorWindow.Tag = null; this._dropIndicatorShown = false; } }
InfragisticsWPF4.v12.2.dll!Infragistics.Windows.Controls.ToolWindow.Close() Line 552 C#
InfragisticsWPF4.v12.2.dll!Infragistics.Windows.Controls.ToolWindow.CloseOverride() Line 564 C#
InfragisticsWPF4.v12.2.dll!Infragistics.Windows.Controls.ToolWindowHostWindow.Infragistics.Windows.Controls.IToolWindowHost.Close() Line 351 C#
InfragisticsWPF4.v12.2.dll!Infragistics.Windows.Controls.ToolWindowHostWindow.CloseHelper() Line 167 C#
PresentationFramework.dll!System.Windows.Window.Close() Line 716 + 0xb bytes C#
//see call stack underneath this posts for more..
protected override void OnLostMouseCapture(MouseEventArgs e)
base.OnLostMouseCapture(e);
SelectionStrategyBase selectionStrategyForItem = ((ISelectionHost) this).GetSelectionStrategyForItem(this._fieldDragManager.DragField);
if ((selectionStrategyForItem == null) || !selectionStrategyForItem.IsReleasingMouseCapture)
//OnDragEnd is called again
this._fieldDragManager.OnDragEnd(e, true);
the second time this function is called it runs to the end en nills the dropIndicatorWindow variabel.
private void OnDragEndHelper(MouseEventArgs mouseEventArgs, bool cancel) { ........... if (this._dropIndicatorWindow != null) { this._dropIndicatorWindow.Dispose(); this._dropIndicatorWindow = null; } }
private void HideDropIndicator() { if (this._dropIndicatorWindow != null) { DropIndicator dropIndicator = DropInfo.GetDropIndicator(this._dropIndicatorWindow); if (dropIndicator != null) { dropIndicator.DropLocation = 0; } this._dropIndicatorWindow.Close();
//only than the first call to OnDragEndHelper continues from here. But now the _dropIndicatorWindow variabel is null so we get the NullReferenceException
this._dropIndicatorWindow.Tag = null; this._dropIndicatorShown = false; } }Here is the callstack when the OnLostMouseCapture is fired:
> InfragisticsWPF4.DataPresenter.v12.2.dll!Infragistics.Windows.DataPresenter.DataPresenterBase.OnLostMouseCapture(System.Windows.Input.MouseEventArgs e) Line 6666 C#
PresentationCore.dll!System.Windows.UIElement.OnLostMouseCaptureThunk(object sender, System.Windows.Input.MouseEventArgs e) Line 3376 + 0xc bytes C#
PresentationCore.dll!System.Windows.Input.MouseEventArgs.InvokeEventHandler(System.Delegate genericHandler, object genericTarget) Line 38 + 0xd bytes C#
PresentationCore.dll!System.Windows.RoutedEventArgs.InvokeHandler(System.Delegate handler, object target) Line 81 + 0x10 bytes C#
PresentationCore.dll!System.Windows.RoutedEventHandlerInfo.InvokeHandler(object target, System.Windows.RoutedEventArgs routedEventArgs) Line 46 + 0x8 bytes C#
PresentationCore.dll!System.Windows.EventRoute.InvokeHandlersImpl(object source, System.Windows.RoutedEventArgs args, bool reRaised) Line 181 C#
PresentationCore.dll!System.Windows.UIElement.RaiseEventImpl(System.Windows.DependencyObject sender, System.Windows.RoutedEventArgs args) Line 5462 + 0x11 bytes C#
PresentationCore.dll!System.Windows.UIElement.RaiseTrustedEvent(System.Windows.RoutedEventArgs args) Line 5533 + 0xa bytes C#
PresentationCore.dll!System.Windows.UIElement.RaiseEvent(System.Windows.RoutedEventArgs args, bool trusted) Line 5442 + 0x9 bytes C#
PresentationCore.dll!System.Windows.Input.InputManager.ProcessStagingArea() Line 363 C#
PresentationCore.dll!System.Windows.Input.InputManager.ProcessInput(System.Windows.Input.InputEventArgs input) Line 284 + 0x7 bytes C#
PresentationCore.dll!System.Windows.Input.MouseDevice.ChangeMouseCapture(System.Windows.IInputElement mouseCapture, System.Windows.Input.IMouseInputProvider providerCapture, System.Windows.Input.CaptureMode captureMode, int timestamp) Line 270 C#
PresentationCore.dll!System.Windows.Input.MouseDevice.PreNotifyInput(object sender, System.Windows.Input.NotifyInputEventArgs e) Line 792 + 0x4a bytes C#
PresentationCore.dll!System.Windows.Input.InputManager.ProcessStagingArea() Line 320 + 0x3c bytes C#
PresentationCore.dll!System.Windows.Input.InputProviderSite.ReportInput(System.Windows.Input.InputReport inputReport) Line 53 + 0xf bytes C#
PresentationCore.dll!System.Windows.Interop.HwndMouseInputProvider.ReportInput(System.IntPtr hwnd, System.Windows.Input.InputMode mode, int timestamp, System.Windows.Input.RawMouseActions actions, int x, int y, int wheel) Line 530 + 0x12 bytes C#
PresentationCore.dll!System.Windows.Interop.HwndMouseInputProvider.FilterMessage(System.IntPtr hwnd, MS.Internal.Interop.WindowMessage msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled) Line 254 + 0x1d bytes C#
PresentationCore.dll!System.Windows.Interop.HwndSource.InputFilterMessage(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled) Line 609 + 0x1b bytes C#
WindowsBase.dll!MS.Win32.HwndWrapper.WndProc(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled) + 0x9b bytes
WindowsBase.dll!MS.Win32.HwndSubclass.DispatcherCallbackOperation(object o) + 0x6b bytes
WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate callback, object args, int numArgs) + 0x52 bytes
WindowsBase.dll!MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(object source, System.Delegate method, object args, int numArgs, System.Delegate catchHandler) + 0x3a bytes
WindowsBase.dll!System.Windows.Threading.Dispatcher.LegacyInvokeImpl(System.Windows.Threading.DispatcherPriority priority, System.TimeSpan timeout, System.Delegate method, object args, int numArgs) + 0x10e bytes
WindowsBase.dll!MS.Win32.HwndSubclass.SubclassWndProc(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam) + 0xf1 bytes
[Native to Managed Transition]
[Managed to Native Transition]
WindowsBase.dll!MS.Win32.SafeNativeMethods.ReleaseCapture() + 0x9 bytes
PresentationCore.dll!System.Windows.Interop.HwndMouseInputProvider.FilterMessage(System.IntPtr hwnd, MS.Internal.Interop.WindowMessage msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled) Line 284 + 0x5 bytes C#
WindowsBase.dll!System.Windows.Threading.DispatcherSynchronizationContext.Wait(System.IntPtr[] waitHandles, bool waitAll, int millisecondsTimeout) + 0x22 bytes
mscorlib.dll!System.Threading.SynchronizationContext.InvokeWaitMethodHelper(System.Threading.SynchronizationContext syncContext, System.IntPtr[] waitHandles, bool waitAll, int millisecondsTimeout) + 0x12 bytes
mscorlib.dll!System.Threading.WaitHandle.InternalWaitOne(System.Runtime.InteropServices.SafeHandle waitableSafeHandle, long millisecondsTimeout, bool hasThreadAffinity, bool exitContext) + 0x22 bytes
mscorlib.dll!System.Threading.WaitHandle.WaitOne(int millisecondsTimeout, bool exitContext) + 0x28 bytes
mscorlib.dll!System.Threading.WaitHandle.WaitOne() + 0x10 bytes
PresentationCore.dll!System.Windows.Input.PenThreadWorker.WorkerRemovePenContext(System.Windows.Input.PenContext penContext) Line 536 + 0x1b bytes C#
PresentationCore.dll!System.Windows.Input.PenContext.Disable(bool shutdownWorkerThread) Line 82 + 0x13 bytes C#
PresentationCore.dll!System.Windows.Input.PenContexts.Disable(bool shutdownWorkerThread) Line 85 + 0xf bytes C#
PresentationCore.dll!System.Windows.Input.StylusLogic.UnRegisterHwndForInput(System.Windows.Interop.HwndSource hwndSource) Line 1951 + 0xc bytes C#
PresentationCore.dll!System.Windows.Interop.HwndStylusInputProvider.Dispose() Line 59 C#
PresentationCore.dll!System.Windows.Interop.HwndSource.Dispose(bool disposing) Line 372 C#
PresentationCore.dll!System.Windows.Interop.HwndSource.OnHwndDisposed(object sender, System.EventArgs args) Line 743 + 0xc bytes C#
WindowsBase.dll!MS.Win32.HwndWrapper.Dispose(bool disposing, bool isHwndBeingDestroyed) + 0x173 bytes
WindowsBase.dll!MS.Win32.HwndWrapper.WndProc(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled) + 0x10e bytes
WindowsBase.dll!MS.Win32.HwndSubclass.DefWndProcWrapper(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam) + 0x50 bytes
WindowsBase.dll!MS.Win32.HwndSubclass.SubclassWndProc(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam) + 0x12d bytes
PresentationFramework.dll!System.Windows.Window.InternalClose(bool shutdown, bool ignoreCancel) Line 1363 + 0x5a bytes C#
InfragisticsWPF4.DataPresenter.v12.2.dll!Infragistics.Windows.DataPresenter.FieldDragManager.HideDropIndicator() Line 714 C#
InfragisticsWPF4.DataPresenter.v12.2.dll!Infragistics.Windows.DataPresenter.FieldDragManager.OnDragEndHelper(System.Windows.Input.MouseEventArgs mouseEventArgs, bool cancel) Line 802 C#
InfragisticsWPF4.DataPresenter.v12.2.dll!Infragistics.Windows.DataPresenter.FieldDragManager.OnDragEnd(System.Windows.Input.MouseEventArgs mouseEventArgs, bool cancel) Line 766 + 0x11 bytes C#
InfragisticsWPF4.DataPresenter.v12.2.dll!Infragistics.Windows.DataPresenter.DataPresenterBase.OnMouseLeftButtonUp(System.Windows.Input.MouseButtonEventArgs e) Line 6676 C#
CustomControl.OnMouseLeftButtonUp(System.Windows.Input.MouseButtonEventArgs e) Line 2223 + 0xb bytes C#
Hello,
Thank you for your post. I have been looking into it and I can say that version 12.2 is now retired and we no longer provide fixes for it. The thing you can do is try your scenario with our latest version (14.2) and see if the issue still occurs. If yes, could you please send us an isolated sample project and steps we need to follow in order to reproduce this on our side and investigate it further for you?
Looking forward for your reply.
I have tested with version 14.2 and the error still occurs.
I DIffed the FieldDragManager class and there was no difference in code with version 12.2.
The sample project, you just needs the steps as described in your example:
But I have attached a test project.
For the reproduction. Attach a debugger. I know this is a little bit cheating, but it occurs more this way.
Set breakpoints at the following places:
FieldDragManager.HideDropIndicator, at the call to _dropIndicatorWindow.Close.
FieldDragManager.HideDropIndicator, at the call to _dropIndicatorWindow.Tag.
Debug the application. Drag the department column to the groupByArea.
Now drag the deparment column a little to the right and than let go. See the screenshot, it is taken at the moment of letting go of the left button. Effectively doing nothing, the grid is still grouped on the department field.
Most of the time you will see that the HideDropIndicator function is called once. But sometimes it's called twice. The second time will the exception occur.
I use Windows 7., .net framework 4.
Sorry, here is the screenshot:
I tested your sample, but I wasn't able to reproduce your issue. Could you please send us an isolated sample, where the issue can be reproduced all the time and more detailed steps we need to follow in order to reproduce this. This way wee will be able to investigate this further for you.
I am just checking the progress of this issue and was wondering if you managed to achieve your goal or if you need any further assistance on the matter.