2009-04-28 24 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存儲與被點擊的樹項目相關聯的數據。 希望它能幫助像我這樣的人。

相關問題