In WPF, wie wähle ich den treeview Artikel unter meinen Cursor auf der rechten Maustaste?
-
18-09-2019 - |
Frage
In WPF, wenn ich auf einem treeview Artikel Rechtsklick Ich möchte es vor zeigt das Kontextmenü ausgewählt / aktiviert werden.
Das klingt ziemlich einfach, aber die Aufnahme eines hierachicalDataTemplate verkompliziert die Dinge ein wenig.
Ich habe folgendes treeview:
<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>
Und hier ist mein Event-Handler ...
private void trv_PreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
TreeViewItem item = sender as TreeViewItem;
if (item != null)
{
item.Focus();
e.Handled = true;
}
}
Beachten Sie, wie ich eine Eventsetter oben hinzuzufügen. Diese fast funktioniert. Aber es wählt nur das Root-Ebene Strukturansichtsknoten (d.h. die Wurzel des übergeordneten Knotens, auf dem I rechte Maustaste). Dies kann wegen meiner hierarchischen Datenvorlage sein? Diese Vorlage kann Kinder gleichen Typs enthalten.
Hier ist meine hierarchische Datenvorlage ...
<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>
Jede Idee, warum nur der Wurzelknoten anstelle von untergeordneten Knoten werden ausgewählt, wenn ich mit der rechten klicken Sie auf?
Lösung
Das ist, weil die ItemContainerStyle nicht von dem untergeordneten Knoten geerbt. Sie müssen den gleichen Eventsetter auf dem ItemContainerStyle o Ihrem HierarchicalDataTemplate hinzuzufügen.
<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>
Andere Tipps
nur einen kurzen Kommentar zum e.Handler=true
von Ihrem Event-Handler.
wie folgt aus:
private void trv_PreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
TreeViewItem item = sender as TreeViewItem;
if (item != null)
{
item.Focus();
// e.Handled = true;
}
}
Ich hatte das gleiche Problem - konnte nicht das richtige ausgewählte Strukturelement erhalten. Und statt PreviewMouseRightButtonDown
Fall verwendet, um I gleiche Falle eines StackPanel
die auch alle nötigen Daten speichert:
<StackPanel DataContext="{Binding}" MouseLeftButtonDown="StackPanel_MouseLeftButtonDown">
....
</StackPanel>
Und die Event-Handler-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
ist mein benutzerdefinierten Typ für eine Daten; myClicked
speichert nun Daten mit dem geklickten Baumelement zugeordnet ist.
Hoffe, dass es jemanden wie mir helfen wird.