gemini icon indicating copy to clipboard operation
gemini copied to clipboard

NullReferenceException when dragging a document window to another docking position without prior undocking

Open odnodn opened this issue 9 years ago • 4 comments

Hi,

nice to see there is still ongoing developement. It has been a long time ago I got to know this project, but couldn't use it due to some issues. No I just tried the 0.62 version within a fresh project from nuget, it builds nice and shows up fine with theme switched to VS2013 dark. But as soon as I am dragging a document window to another position indicated by the visual clues I get the aformentioned exeption. Dragging tool windows to other positions and pinning/unpinning them works fine. But If I first drag a window (code editor window, 2 opened documents) to an undocked position and then drag it to the desired docking position there will be no error. I have to do the same to redock the document window to the old position. It seems the reference to the window which is about to be repositioned gets lost if you are not bringging it in an undocked position. Is this a problem due to avalon dock a rather due to the editor plugin? What can I do to solve this issue?

Thanks for your kind help.

Oliver

NullReferenceException: Object reference not set to an instance of an object bei System.Windows.Interop.HwndKeyboardInputProvider.System.Windows.Input.IKeyboardInputProvider.AcquireFocus(Boolean checkOnly) bei System.Windows.Input.KeyboardDevice.TryChangeFocus(DependencyObject newFocus, IKeyboardInputProvider keyboardInputProvider, Boolean askOld, Boolean askNew, Boolean forceToNullIfFailed) bei System.Windows.Input.KeyboardDevice.Focus(DependencyObject focus, Boolean askOld, Boolean askNew, Boolean forceToNullIfFailed) bei System.Windows.Input.KeyboardDevice.Focus(IInputElement element) bei System.Windows.UIElement.Focus() bei System.Windows.Input.KeyboardNavigation.Navigate(DependencyObject currentElement, TraversalRequest request, ModifierKeys modifierKeys, DependencyObject firstElement) bei System.Windows.FrameworkElement.MoveFocus(TraversalRequest request) bei Gemini.Modules.CodeEditor.Views.CodeEditorView.<.ctor>b__0(Object sender, RoutedEventArgs e) bei System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs) bei System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised) bei System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args) bei System.Windows.UIElement.RaiseEvent(RoutedEventArgs e) bei System.Windows.BroadcastEventHelper.BroadcastEvent(DependencyObject root, RoutedEvent routedEvent) bei System.Windows.BroadcastEventHelper.BroadcastLoadedEvent(Object root) bei MS.Internal.LoadedOrUnloadedOperation.DoWork() bei System.Windows.Media.MediaContext.FireLoadedPendingCallbacks() bei System.Windows.Media.MediaContext.FireInvokeOnRenderCallbacks() bei System.Windows.Media.MediaContext.RenderMessageHandlerCore(Object resizedCompositionTarget) bei System.Windows.Media.MediaContext.RenderMessageHandler(Object resizedCompositionTarget) bei System.Windows.Media.MediaContext.Resize(ICompositionTarget resizedCompositionTarget) bei System.Windows.Interop.HwndTarget.OnResize() bei System.Windows.Interop.HwndTarget.HandleMessage(WindowMessage msg, IntPtr wparam, IntPtr lparam) bei System.Windows.Interop.HwndSource.HwndTargetFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled) bei MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled) bei MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o) bei System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs) bei System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler) bei System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs) bei MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam) bei MS.Win32.UnsafeNativeMethods.CallWindowProc(IntPtr wndProc, IntPtr hWnd, Int32 msg, IntPtr wParam, IntPtr lParam) bei MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam) bei MS.Win32.UnsafeNativeMethods.CallWindowProc(IntPtr wndProc, IntPtr hWnd, Int32 msg, IntPtr wParam, IntPtr lParam) bei MS.Win32.HwndSubclass.DefWndProcWrapper(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam) bei MS.Win32.UnsafeNativeMethods.CallWindowProc(IntPtr wndProc, IntPtr hWnd, Int32 msg, IntPtr wParam, IntPtr lParam) bei MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam) bei MS.Win32.UnsafeNativeMethods.CallWindowProc(IntPtr wndProc, IntPtr hWnd, Int32 msg, IntPtr wParam, IntPtr lParam) bei MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)

odnodn avatar Mar 17 '16 18:03 odnodn

any ideas??

odnodn avatar May 04 '16 08:05 odnodn

It was really hard to figure out why and exact how this happens. See the video for better understanding. In the first part of the video (0-30s) you will see that when dragging document out of the docking, the window disappear and when docking it again an error is thrown (NullReferenceException).

The second part, I've commented the code where Gemini tries to focus on loaded event. When the code is commented out, the error does not occur and the window is shown.

The error also occurs in any View that uses KeyboardFocusBehavior, because this class also tries to set Keyboard Focus.

It seems that the error is not related to Gemini itself, as you can see in the Stack Trace. It seems not related to AvalonDock either. It seems a combination of steps that leads to an error in the .net Framework itself.

   at System.Windows.Interop.HwndKeyboardInputProvider.System.Windows.Input.IKeyboardInputProvider.AcquireFocus(Boolean checkOnly)
   at System.Windows.Input.KeyboardDevice.TryChangeFocus(DependencyObject newFocus, IKeyboardInputProvider keyboardInputProvider, Boolean askOld, Boolean askNew, Boolean forceToNullIfFailed)
   at System.Windows.Input.KeyboardDevice.Focus(DependencyObject focus, Boolean askOld, Boolean askNew, Boolean forceToNullIfFailed)
   at System.Windows.Input.KeyboardDevice.Focus(IInputElement element)
   at Xceed.Wpf.AvalonDock.Controls.FocusElementManager.SetFocusOnLastElement(ILayoutElement model)
   at Xceed.Wpf.AvalonDock.DockingManager.OnLayoutRootPropertyChanged(Object sender, PropertyChangedEventArgs e)
   at System.ComponentModel.PropertyChangedEventHandler.Invoke(Object sender, PropertyChangedEventArgs e)
   at Xceed.Wpf.AvalonDock.Layout.LayoutElement.RaisePropertyChanged(String propertyName)
   at Xceed.Wpf.AvalonDock.Layout.LayoutRoot.InternalSetActiveContent(LayoutContent currentValue, LayoutContent newActiveContent)
   at Xceed.Wpf.AvalonDock.Layout.LayoutRoot.set_ActiveContent(LayoutContent value)
   at Xceed.Wpf.AvalonDock.Layout.LayoutContent.set_IsActive(Boolean value)
   at Xceed.Wpf.AvalonDock.Controls.LayoutDocumentControl.OnPreviewGotKeyboardFocus(KeyboardFocusChangedEventArgs e)
   at System.Windows.UIElement.OnPreviewGotKeyboardFocusThunk(Object sender, KeyboardFocusChangedEventArgs e)
   at System.Windows.Input.KeyboardFocusChangedEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)
   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.UIElement.RaiseEvent(RoutedEventArgs args, Boolean trusted)
   at System.Windows.Input.InputManager.ProcessStagingArea()
   at System.Windows.Input.InputManager.ProcessInput(InputEventArgs input)
   at System.Windows.Input.KeyboardDevice.TryChangeFocus(DependencyObject newFocus, IKeyboardInputProvider keyboardInputProvider, Boolean askOld, Boolean askNew, Boolean forceToNullIfFailed)
   at System.Windows.Input.KeyboardDevice.Focus(DependencyObject focus, Boolean askOld, Boolean askNew, Boolean forceToNullIfFailed)
   at System.Windows.Input.KeyboardDevice.Focus(IInputElement element)
   at System.Windows.UIElement.Focus()
   at System.Windows.Input.KeyboardNavigation.Navigate(DependencyObject currentElement, TraversalRequest request, ModifierKeys modifierKeys, DependencyObject firstElement)
   at System.Windows.FrameworkElement.MoveFocus(TraversalRequest request)
   at Gemini.Modules.CodeEditor.Views.CodeEditorView.<.ctor>b__2_0(Object sender, RoutedEventArgs e) in C:\Users\joberto.diniz\AppData\Local\WDG Automation\downloads\gemini-master\src\Gemini.Modules.CodeEditor\Views\CodeEditorView.xaml.cs:line 17
   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.RaiseEvent(RoutedEventArgs e)
   at System.Windows.BroadcastEventHelper.BroadcastEvent(DependencyObject root, RoutedEvent routedEvent)
   at System.Windows.BroadcastEventHelper.BroadcastLoadedEvent(Object root)
   at MS.Internal.LoadedOrUnloadedOperation.DoWork()
   at System.Windows.Media.MediaContext.FireLoadedPendingCallbacks()
   at System.Windows.Media.MediaContext.FireInvokeOnRenderCallbacks()
   at System.Windows.Media.MediaContext.RenderMessageHandlerCore(Object resizedCompositionTarget)
   at System.Windows.Media.MediaContext.RenderMessageHandler(Object resizedCompositionTarget)
   at System.Windows.Media.MediaContext.Resize(ICompositionTarget resizedCompositionTarget)
   at System.Windows.Interop.HwndTarget.OnResize()
   at System.Windows.Interop.HwndTarget.HandleMessage(WindowMessage msg, IntPtr wparam, IntPtr lparam)
   at System.Windows.Interop.HwndSource.HwndTargetFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
   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)

As a workaround, Gemini needs to set focus only once. Loaded event can occur multiple times, and the error is thrown when dragging, and when dragging the Loaded event is fired again. Workaround on CodeEditorView.xaml.cs:

public CodeEditorView()
        {
            InitializeComponent();
            Loaded += CodeEditorView_Loaded;
        }

        private void CodeEditorView_Loaded(object sender, System.Windows.RoutedEventArgs e)
        {
            Loaded -= CodeEditorView_Loaded; //NOTE: here we remove the subscription...
            MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
        }

Apply the same logic in the KeyboardFocusBehavior and you will be fine. cc @tgjones what a nasty bug I must say

JobaDiniz avatar Dec 28 '18 13:12 JobaDiniz