2009-04-28 28 views
17

Trong WPF, khi tôi nhấp chuột phải vào một mục treeview tôi muốn nó được chọn/kích hoạt trước khi hiển thị menu ngữ cảnh.Trong WPF, làm cách nào để chọn mục treeview bên dưới con trỏ của tôi khi nhấp chuột phải?

Điều này nghe có vẻ khá đơn giản, nhưng sự bao gồm của một hierachicalDataTemplate làm phức tạp mọi thứ một chút.

Tôi có treeview sau:

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

Và đây là xử lý sự kiện của tôi ...

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

} 

Lưu ý làm thế nào tôi thêm một EventSetter trên. ALMOST này hoạt động. Nhưng nó chỉ chọn nút treeview cấp gốc (nghĩa là nút gốc của nút mà tôi nhấp chuột phải). Điều này có thể do mẫu dữ liệu phân cấp của tôi? Mẫu này có thể chứa con của LOẠI CÙNG.

Đây là của tôi Mẫu dữ liệu phân cấp ...

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

Bất kỳ ý tưởng về lý do tại sao chỉ có nút gốc thay vì nút con được lựa chọn khi nhấn chuột phải?

Trả lời

15

Đó là vì ItemContainerStyle không được thừa hưởng bởi các nút con. Bạn cần phải thêm cùng một EventSetter vào ItemContainerStyle o HierarchicalDataTemplate của bạn.

<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

Cảm ơn Denis. Điều đó có ý nghĩa. Tôi vẫn nhận được hành vi kỳ lạ mặc dù ... nếu tôi đặt ItemContainerStyle trên cả hai hierarchicalDataTemplate và treeview, sau đó nó vẫn làm như trước. Nếu tôi chỉ đặt ItemContainerStyle trên hierarchicalDataTemplate, nó cũng làm như vậy, nhưng lần này chỉ dành cho các nút ở cấp độ thứ hai. Lạ thật. Bất kỳ ý tưởng? – willem

+1

Aah, thú vị. Điều đó đã xảy ra do e.Handled = true. Không chắc chắn 100% lý do tại sao ... – willem

+4

Vì bạn đang xử lý sự kiện đường hầm (sự kiện PreviewXXX). Những sự kiện này đi từ trên xuống dưới cùng của cây, vì vậy nếu bạn đặt e.Handled = true tại gốc, nó sẽ dừng ở đó và không đường hầm xuống cây đến mục của bạn. –

5

chỉ cần nhận xét e.Handler=true từ trình xử lý sự kiện của bạn.

như thế này:

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

} 
+0

Tính năng này hoạt động với chế độ xem nhiều cấp độ của tôi. '' 'e.Handled = true;' '' sẽ dừng sự kiện xử lý và dừng nó ở cấp độ đầu tiên, đó là lý do tại sao chỉ có thể chọn phần tử gốc hoặc phần tử cấp đầu tiên. – Adison

0

tôi đã cùng một vấn đề - không thể có được mục cây được lựa chọn thích hợp. Và thay vì sử dụng PreviewMouseRightButtonDown sự kiện tôi đã sử dụng cùng một sự kiện của một StackPanel mà cũng lưu trữ toàn bộ dữ liệu cần thiết:

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

và xử lý sự kiện code-behind:

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 là kiểu tùy chỉnh của tôi cho một dữ liệu ; myClicked hiện lưu trữ dữ liệu được liên kết với mục cây được nhấp. Hy vọng nó sẽ giúp một người như tôi.

Các vấn đề liên quan