En WPF, comment puis-je sélectionner l'élément TreeView sous mon curseur sur le bouton droit sur?

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

  •  18-09-2019
  •  | 
  •  

Question

Dans WPF, quand je clic droit sur un élément de TreeView Je voudrais qu'il soit sélectionné / Activé avant d'afficher le menu contextuel.

Cela semble assez simple, mais l'inclusion d'un hierachicalDataTemplate complique les choses un peu.

Je le treeview suivant:

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

Et voici mon gestionnaire d'événements ...

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

}

Notez comment ajouter un EventSetter ci-dessus. Cela fonctionne PRESQUE. Mais il ne sélectionne que le nœud TreeView niveau racine (à savoir le parent racine du nœud sur lequel je clique à droite). Cela peut être à cause de mon modèle de données hiérarchique? Ce modèle peut contenir des enfants DU MEME TYPE.

Voici mon modèle de données hiérarchique ...

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

Toute idée pourquoi seul le nœud racine au lieu de nœuds enfants sont sélectionnés lorsque je clic droit?

Était-ce utile?

La solution

C'est parce que le ItemContainerStyle n'est pas hérité par les nœuds enfants. Vous devez ajouter le même EventSetter sur le ItemContainerStyle o votre 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>

Autres conseils

juste commenter le e.Handler=true de votre gestionnaire d'événements.

comme ceci:

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

}

J'ai eu le même problème - n'a pas pu obtenir le bon élément de l'arbre sélectionné. Et au lieu d'utiliser événement PreviewMouseRightButtonDown je même événement d'un StackPanel qui stocke également toutes les données nécessaire:

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

Et le gestionnaire d'événements 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 est mon type personnalisé pour les données; myClicked stocke désormais les données associées à l'élément de l'arborescence cliquée. Je espère que ça va aider quelqu'un comme moi.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top