En WPF, ¿cómo selecciono el punto de vista de árbol bajo mi cursor en haga clic derecho?

StackOverflow https://stackoverflow.com/questions/797966

  •  18-09-2019
  •  | 
  •  

Pregunta

En WPF, cuando haga clic en un elemento de árbol me gustaría que para ser seleccionado / activado antes de mostrar el menú contextual.

Esto suena bastante simple, pero la inclusión de un hierachicalDataTemplate complica las cosas un poco.

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

}

Tenga en cuenta cómo agrego una EventSetter anteriormente. Esto funciona CASI. Pero sólo selecciona el nodo de árbol de 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árquica? Esta plantilla puede contener niños de la misma TYPE.

Aquí está mi plantilla de datos jerárquica ...

<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é sólo el nodo raíz en lugar de los nodos secundarios son seleccionados cuando haga clic derecho?

¿Fue útil?

Solución

Esto se debe a la ItemContainerStyle no es heredado por los nodos secundarios. Es necesario añadir la misma 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>

Otros consejos

acaba de comentar el e.Handler=true de su controlador de eventos.

como esto:

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

}

Yo tenía el mismo problema - no podía conseguir el artículo árbol seleccionado adecuada. Y en lugar de utilizar PreviewMouseRightButtonDown caso utilicé mismo evento de un StackPanel que también almacena todos los datos necesaria;

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

Y el controlador de eventos de código subyacente:

 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 datos; myClicked ahora almacena un dato asociado con el elemento del árbol se ha hecho clic. Esperamos que ayude a alguien como yo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top