2016-07-12 27 views
5

treeviewitemを右クリックすると、処理されないInvalidOperationExceptionが発生することがあります。コードの中で右クリックした行を選択します:なぜクリックツリーが 'System.Windows.Documents.Run'がVisualまたはVisual3DのInvalidOperationExceptionではありませんか?

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; 
      } 
    } 

上記のstacktraceによると、問題の原因は次のとおりです。

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> 

スタックトレース:

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" 

私は時々これを再現することができます。私の同僚は、アイテム1を左クリックし、アイテム2を右クリックすると、毎回これが特定のツリーで生成されると述べました。

+0

「実行」はビジュアルではなく、別の処理が必要です。 'VisualUpwardSearch(DependencyObjectとしてのe.Source);'はすでにあなたのために修正していますか?また、クリックを再現するには、画像ではなくラベルで行う必要があります! –

+0

私は画像ではなくテキストブロックをクリックしていますが、今は数分間クリックしてしまい、それを再現できません。この変更によって違いが生じるかどうかは分かりません。 –

+0

さらにe.Sourceに変更すると、アイテムの親が選択されます –

答えて

6

ラベルのテキストのどこかをクリックすると問題が再現されます。この場合、e.OriginalSourceは、LabelまたはTextBoxの内部構成の一部であるRunオブジェクトになります。 Run要素はVisualクラスから継承されていないため、ビジュアルツリーの一部にすることはできません。この場合、VisualTreeHelper.GetParent(source);InvalidOperationExceptionを送出します。

最も簡単な解決策は、各テキストコントロール(あなたのケースでLabelIsHitTestVisible="False"を作ることになり、これは、イベントのe.OriginalSourceになることはありませんことを意味し、ヒットテストロジックからこれらのコントロールを除外し、代わりにそれは親がになりますピックアップされ、親はおそらくVisual要素になります。

+0

ありがとう!これが修正されたかどうかは徹底的なテストによってわかります。私にとっては、再生することはほとんど不可能でした。クリックして1時間で私は例外を2回得ることができました。説明のため+1。 「最も可能性の高い部分」について教えていただけますか? IsHitTestVisible = "False"に設定した場合でもこれが起こりますか? –

+0

安全な側に追加するだけで、 "if(source is Visual)"チェックを追加できますか? –

+0

いいえ、チェックを気にしないで、将来の問題を隠すかもしれませんが、IsHitTestVisibleをfalseに設定せずにテンプレートに他のテキスト要素を追加することがあるため、 "最も可能性が高いVisual"と述べました。あなたのケースでは100%安全です。IsHitTestVisibleをテンプレートのルートStackPanelに置いて、テンプレート内の他のテキスト要素の問題を避けることができます。ありがとう。 –

関連する問題