Why is the click tree throwing a "System.Windows.Documents.Run" not visual or Visual3D 'InvalidOperationException?

Sometimes right-clicking on a tree leads to an unhandled InvalidOperationException. In the code behind, I select a line with a right click:

static TreeViewItem VisualUpwardSearch(DependencyObject source) { while (source != null && !(source is TreeViewItem)) source = VisualTreeHelper.GetParent(source); return source as TreeViewItem; } private void OnPreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e) { TreeViewItem treeViewItem = VisualUpwardSearch(e.OriginalSource as DependencyObject); if (treeViewItem != null) { treeViewItem.Focus(); e.Handled = true; } } 

According to the above, stacktrace is the source of the problem.

XAML:

 <UserControl.Resources> <HierarchicalDataTemplate ItemsSource="{Binding ClassesItemsSource}" DataType="{x:Type pnls:FavoriteObjectTableViewModel}"> <StackPanel Orientation="Horizontal"> <Image Source="{Binding Converter={StaticResource nameToBitmapSource}}" DataContext="{Binding Bitmap}" /> <Label Content="{Binding TableName}"/> </StackPanel> </HierarchicalDataTemplate> <DataTemplate DataType="{x:Type pnls:FavoriteObjectClassViewModel}"> <StackPanel Orientation="Horizontal"> <Image Source="{Binding Bitmap, Converter={StaticResource UriToCachedImageConverter}}"/> <Label Content="{Binding ClassName}"/> </StackPanel> </DataTemplate> </UserControl.Resources> <TreeView Name="Insert_ObjectTreeIE" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" ItemsSource="{Binding TablesItemsSource}"> <TreeView.ItemContainerStyle> <Style TargetType="TreeViewItem"> <Setter Property="IsSelected" Value="{Binding IsSelected}" /> <Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" /> <EventSetter Event="PreviewMouseRightButtonDown" Handler="OnPreviewMouseRightButtonDown"></EventSetter> <EventSetter Event="MouseDoubleClick" Handler="OnMouseDoubleClick" /> </Style> </TreeView.ItemContainerStyle> </TreeView> 

Stacktrace:

 e.StackTrace " at MS.Internal.Media.VisualTreeUtils.AsVisual(DependencyObject element, Visual& visual, Visual3D& visual3D)\r\n at MS.Internal.Media.VisualTreeUtils.AsNonNullVisual(DependencyObject element, Visual& visual, Visual3D& visual3D)\r\n at System.Windows.Media.VisualTreeHelper.GetParent(DependencyObject reference)\r\n at Tekla.Nis.Application.Shared.UI.Panels.FavoriteObjectsView.VisualUpwardSearch(DependencyObject source) in c:\\XXX\\161wpf\\src\\SharedAppFeature\\Panels\\FavoriteObjectsView.xaml.cs:line 45\r\n at Application.Shared.UI.Panels.FavoriteObjectsView.OnPreviewMouseRightButtonDown(Object sender, MouseButtonEventArgs e) in c:\\XXX\\161wpf\\src\\NisSharedAppFeature\\Panels\\FavoriteObjectsView.xaml.cs:line 52\r\n at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)\r\n at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)\r\n at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)\r\n at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)\r\n at System.Windows.UIElement.ReRaiseEventAs(DependencyObject sender, RoutedEventArgs args, RoutedEvent newEvent)\r\n at System.Windows.UIElement.OnPreviewMouseDownThunk(Object sender, MouseButtonEventArgs e)\r\n at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)\r\n at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)\r\n at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)\r\n at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)\r\n at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)\r\n at System.Windows.ContentElement.RaiseTrustedEvent(RoutedEventArgs args)\r\n at System.Windows.Input.InputManager.ProcessStagingArea()\r\n at System.Windows.Input.InputManager.ProcessInput(InputEventArgs input)\r\n at System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport)\r\n at System.Windows.Interop.HwndMouseInputProvider.ReportInput(IntPtr hwnd, InputMode mode, Int32 timestamp, RawMouseActions actions, Int32 x, Int32 y, Int32 wheel)\r\n at System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr hwnd, WindowMessage msg, IntPtr wParam, IntPtr lParam, Boolean& handled)\r\n at System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)\r\n at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)\r\n at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)\r\n at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)\r\n at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)\r\n at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)\r\n at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)\r\n at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)\r\n at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)\r\n at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)\r\n at System.Windows.Application.RunDispatcher(Object ignore)\r\n at System.Windows.Application.RunInternal(Window window)\r\n at System.Windows.Application.Run(Window window)\r\n at System.Windows.Application.Run()\r\n at "my application start location" 

I can reproduce it only occasionally. My colleague said that the left click element 1 and the right click element 2 does this every time in a particular tree.

+10
source share
2 answers

Problems are reproduced when you click somewhere in the text label. In this case, the e.OriginalSource will be a Run object that is part of the inner composition of the Label or TextBox . The Run element is not inherited from the Visual class, therefore it cannot be part of the visual tree, in this case VisualTreeHelper.GetParent(source); will throw an InvalidOperationException .

The easiest solution is to make each text control ( Label in your case) IsHitTestVisible="False" , this will exclude these controls from the test logic, which means that it will never be an e.OriginalSource event, instead the parent will be raised and, most likely the parent will be a Visual element.

+15
source

I found that starting a search with a parent works in my case. My TreeViewItem text consisted of several runs, so I could not turn off the hit test.

  private void TextBlock_PreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e) { TreeViewItem treeViewItem; if (e.OriginalSource is System.Windows.Documents.Run) treeViewItem = VisualUpwardSearch(((System.Windows.Documents.Run)e.OriginalSource).Parent as DependencyObject); else treeViewItem = VisualUpwardSearch(e.OriginalSource as DependencyObject); if (treeViewItem != null) { treeViewItem.IsSelected = true; e.Handled = true; } } 
0
source

All Articles