2016-07-12 1 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

'Run'은 비주얼이 아니며 별도의 처리가 필요합니다. 'VisualUpwardSearch (DependencyObject로서의 e.Source);'가 이미 당신을 위해 그것을 수정 했습니까? 또한 : 이미지를 표시하지 않고 라벨을 클릭하여 재현해야합니다! –

+0

나는 이미지가 아니라 텍스트 상자를 클릭하지만 지금은 몇 분 동안 클릭하고 그것을 재현 할 수 없다. 그래서이 변화가 차이를 가져올 지 모르겠습니다. –

+0

더하기 e.Source로 변경하면 항목 부모가 –

답변

6

레이블의 텍스트를 클릭하면 문제가 재현됩니다. 이 경우 e.OriginalSourceLabel 또는 TextBox의 내부 구성의 일부인 Run 개체가됩니다. Run 요소는 Visual 클래스에서 상속되지 않으므로 시각적 트리의 일부가 될 수 없습니다.이 경우 VisualTreeHelper.GetParent(source);InvalidOperationException이됩니다. (귀하의 경우 Label)

가장 쉬운 해결책은 각 텍스트 컨트롤을하는 것 IsHitTestVisible="False",이 대신 부모가 될 것입니다,이 이벤트의 e.OriginalSource 결코 것을 의미 히트 테스트 로직에서 이러한 컨트롤을 제외됩니다 픽업하면 부모는 Visual 요소가 될 가능성이 큽니다.

+0

고맙습니다! 철저한 테스트를 통해 이것이 수정되었는지 여부를 알 수 있습니다. 나를 위해 그것을 재현하는 것이 거의 불가능했습니다. 클릭의 1h에 나는 예외를 2 번 알아들을 수 있었다. 설명을 위해 +1. '가장 가능성있는 부분'에 대해 말해 줄 수 있습니까? IsHitTestVisible = "False"로 설정하더라도이 문제가 발생할 수 있습니까? –

+0

"if (source is Visual)"라는 추가 검사가 안전한면에 추가 될 수 있습니까? –

+0

아니요, 수표에 신경 쓰지 마세요. 미래의 문제를 숨길 수 있습니다. IsHitTestVisible을 false로 설정하지 않고 템플릿에 다른 텍스트 요소를 추가하는 경우가있을 수 있으므로 "가장 가능성있는 비주얼"이라고 언급했습니다. 100 % 안전하다면 템플릿의 다른 텍스트 요소에 문제가 발생하지 않도록 IsHitTestVisible을 템플릿의 루트 StackPanel에만 놓을 수 있습니다. 덕분에 –

관련 문제