wpf - reemplazar - hacer doble click con teclado
En WPF, ¿cómo selecciono el elemento de vista de árbol bajo mi cursor al hacer clic con el botón derecho? (3)
En WPF, cuando hago clic con el botón derecho en un elemento de vista de árbol, deseo que se seleccione / active antes de mostrar el menú contextual.
Esto suena bastante simple, pero la inclusión de una plantilla de datos jerárquica complica un poco las cosas.
Tengo la siguiente vista de árbol:
<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>
Y aquí está mi controlador de eventos ...
private void trv_PreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
TreeViewItem item = sender as TreeViewItem;
if (item != null)
{
item.Focus();
e.Handled = true;
}
}
Observe cómo agrego un EventSetter arriba. Esto funciona CASI Pero solo selecciona el nodo de vista de árbol a nivel raíz (es decir, el padre raíz del nodo en el que hago clic derecho). Esto puede ser debido a mi plantilla de datos jerárquicos? Esta plantilla puede contener hijos del mismo tipo.
Aquí está mi plantilla de datos jerárquicos ...
<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>
¿Alguna idea de por qué solo el nodo raíz en lugar de los nodos secundarios se seleccionan cuando hago clic con el botón derecho?
Eso es porque el ItemContainerStyle no es heredado por los nodos secundarios. Debe agregar el mismo EventSetter en el ItemContainerStyle o su HierarchicalDataTemplate.
<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>
Tuve el mismo problema: no pude obtener el elemento del árbol seleccionado adecuado. Y en lugar de usar el evento PreviewMouseRightButtonDown
usé el mismo evento de StackPanel
que también almacena todos los datos necesarios:
<StackPanel DataContext="{Binding}" MouseLeftButtonDown="StackPanel_MouseLeftButtonDown">
....
</StackPanel>
Y el controlador de eventos de código detrás:
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
es mi tipo personalizado para un dato; myClicked
ahora almacena los datos asociados con el elemento del árbol en el que se hizo clic. Espero que ayude a alguien como yo.
simplemente comente el e.Handler=true
desde su controlador de eventos.
Me gusta esto:
private void trv_PreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
TreeViewItem item = sender as TreeViewItem;
if (item != null)
{
item.Focus();
// e.Handled = true;
}
}