2009-04-28 62 views
17

WPFでは、ツリービュー項目を右クリックすると、コンテキストメニューを表示する前に選択/アクティブ化したいと思っています。WPFでは、右クリックするとカーソル下のツリービュー項目をどのように選択できますか?

これはかなり単純ですが、hierachicalDataTemplateを含めると少し複雑になります。私は上記のEventSetterを追加する方法をここで

<TreeView 
      x:Name="trv" 
      ContextMenu="{StaticResource contextMenu}" 
      ItemTemplate="{StaticResource treeHierarchicalDataTemplate}" 
      ItemsSource="{Binding Source={StaticResource meetingItems}}" > 

      <TreeView.ItemContainerStyle> 
       <Style TargetType="{x:Type TreeViewItem}"> 
        <EventSetter Event="TreeViewItem.PreviewMouseRightButtonDown" Handler="trv_PreviewMouseRightButtonDown"/> 
        <Setter Property="IsExpanded" Value="True"></Setter> 
       </Style> 
      </TreeView.ItemContainerStyle> 
     </TreeView> 

そして、私のイベントハンドラがある...

private void trv_PreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e) 
{ 
    TreeViewItem item = sender as TreeViewItem; 
    if (item != null) 
    { 
     item.Focus(); 
     e.Handled = true; 
    } 

} 

注:

は、私は、次のツリービューを持っています。このALMOSTは機能します。しかし、それは、ルートレベルツリービューノード(すなわち、右クリックするノードのルート親)のみを選択する。これは私の階層的なデータテンプレートのためかもしれません?このテンプレートには、同じタイプの子を含めることができます。ここで

私の階層的なデータテンプレートがある...

<HierarchicalDataTemplate x:Key="treeHierarchicalDataTemplate" 
          ItemsSource="{Binding Path=ChildMeetingItems}"> 
    <HierarchicalDataTemplate.Triggers> 
     <DataTrigger Binding="{Binding Path=Red}" Value="True"> 
      <Setter TargetName="img" Property="Image.Source" Value="pack://siteoforigin:,,,/images/bookRed.png"></Setter> 
     </DataTrigger> 
    </HierarchicalDataTemplate.Triggers> 
    <StackPanel 
     x:Name="treeViewItemPanel" 
     Background="Transparent" 
     Orientation="Horizontal"> 
     <Image Width="16" Height="16" x:Name="img" Margin="0,0,4,0" Source="pack://siteoforigin:,,,/images/bookGreen.png"></Image> 
     <TextBlock Foreground="DarkGray" Text="{Binding DisplayIndex}" Margin="0,0,5,0"></TextBlock> 
     <TextBlock Text="{Binding Summary}"></TextBlock> 
    </StackPanel> 
</HierarchicalDataTemplate> 

私は右クリックしたときに代わりに子ノードのルートノードのみが選択されている理由上の任意のアイデア?

答えて

15

これは、ItemContainerStyleが子ノードによって継承されないためです。 HierarchicalDataTemplateのItemContainerStyleに同じEventSetterを追加する必要があります。

<HierarchicalDataTemplate x:Key="treeHierarchicalDataTemplate" 
          ItemsSource="{Binding Path=ChildMeetingItems}"> 
    <HierarchicalDataTemplate.Triggers> 
     <DataTrigger Binding="{Binding Path=Red}" Value="True"> 
      <Setter TargetName="img" Property="Image.Source" Value="pack://siteoforigin:,,,/images/bookRed.png"></Setter> 
     </DataTrigger> 
    </HierarchicalDataTemplate.Triggers> 
    <StackPanel 
     x:Name="treeViewItemPanel" 
     Background="Transparent" 
     Orientation="Horizontal"> 
     <Image Width="16" Height="16" x:Name="img" Margin="0,0,4,0" Source="pack://siteoforigin:,,,/images/bookGreen.png"></Image> 
     <TextBlock Foreground="DarkGray" Text="{Binding DisplayIndex}" Margin="0,0,5,0"></TextBlock> 
     <TextBlock Text="{Binding Summary}"></TextBlock> 
    </StackPanel> 

<HierarchicalDataTemplate.ItemContainerStyle> 
       <Style TargetType="{x:Type TreeViewItem}"> 
        <EventSetter Event="TreeViewItem.PreviewMouseRightButtonDown" Handler="trv_PreviewMouseRightButtonDown"/>      
       </Style> 
      </HierarchicalDataTemplate.ItemContainerStyle> 
</HierarchicalDataTemplate> 
+0

ありがとうDenis。それは理にかなっている。私はまだ奇妙な動作をしています...もし私がhierarchicalDataTemplateとtreeviewの両方でItemContainerStyleを設定すると、前と同じように動作します。 hierarchicalDataTemplateでItemContainerStyleのみを設定すると、同じことが実行されますが、今度は2番目のレベルのノードのみです。奇妙な。何か案は? – willem

+1

ああ、面白いです。 e.Handled = trueのために起こっていました。あなたがトンネリングイベント(PreviewXXXイベント)を処理しているため、理由は100%ではありません。 – willem

+4

これらのイベントはツリーの上から下に行くので、ルートでe.Handled = trueを設定した場合は、そこで停止し、ツリーを項目にトンネリングしません。 –

5

あなたのイベントハンドラからe.Handler=trueとコメントしてください。このような

private void trv_PreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e) 
{ 
    TreeViewItem item = sender as TreeViewItem; 
    if (item != null) 
    { 
     item.Focus(); 
     // e.Handled = true; 
    } 

} 
+0

これは私のマルチレベルのツリービューで動作します。 '' 'e.Handled = true;' ''はハンドライベントを停止し、最初のレベルで停止します。そのため、ルート要素または第1レベルの要素だけが選択できます。 – Adison

0

私は同じ問題を抱えていた - 適切な選択されたツリー項目を取得できませんでした。そして、代わりにPreviewMouseRightButtonDownイベントを使用して、私はまた、すべてのニードフルデータを格納するStackPanelの同じイベントを使用:

<StackPanel DataContext="{Binding}" MouseLeftButtonDown="StackPanel_MouseLeftButtonDown"> 
.... 
</StackPanel> 

とイベントハンドラのコードビハインド:

private void StackPanel_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) 
     { 
      StackPanel panel = sender as StackPanel; 
      if(panel==null)return; 
      MyTreeViewItem myClicked = panel.DataContext as MyTreeViewItem; 
      if (myClicked == null) return; 
... 
} 

MyTreeViewItemは、データのための私のカスタムタイプであります; myClickedは、クリックされたツリー項目に関連付けられたデータを保存するようになりました。 それは私のような人に役立つことを願っています。

関連する問題