2009-04-28 41 views
17

在WPF中,当我右键点击一个树形视图项时,我希望它在显示上下文菜单之前被选定/激活。在WPF中,如何在右键单击我的光标下选择树形视图项目?

这听起来很简单,但包含hierachicalDataTemplate会使事情稍微复杂一些。

我有以下的树视图:

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

} 

注意我怎么加上面的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> 

上为什么只有根节点不是子节点,当我用鼠标右键单击选中的任何想法?

回答

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

谢谢丹尼斯。这就说得通了。我仍然得到奇怪的行为,虽然...如果我在层次数据模板和树视图上设置了ItemContainerStyle,那么它仍然和以前一样。如果我只在hierarchicalDataTemplate上设置ItemContainerStyle,它会做同样的事情,但是这次只能在第二级上使用节点。奇怪。有任何想法吗? – willem 2009-04-28 14:10:12

+1

啊,有趣。这是由于e.Handled = true而发生的。不是100%确定为什么... – willem 2009-04-28 14:36:38

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

我有同样的问题 - 不能得到正确的选择树项目。而不是使用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存储与被点击的树项目相关联的数据。 希望它能帮助像我这样的人。

相关问题