我和这个问题有同样的问题,我希望 TreeViewItem 在显示其上下文菜单时仍然看起来被选中。但是,在我的树中,每个级别都有不同类型的对象,因此我希望每个级别都有不同的 ContextMenu。我正在使用 HierachicalDataTemplate 完成此操作。所以我有以下 XAML:
<Window x:Class="Project.MainWindow">
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Project" ContentRendered="Window_ContentRendered">
<Grid>
<Grid.Resources>
<DataTemplate x:Key="VolumeTemplate">
<StackPanel Orientation="Horizontal">
<Image Source="{StaticResource VolumeIcon}" Margin="3,3,3,3" />
<TextBlock Text="{Binding Path=Name}" Margin="3,3,3,3">
<TextBlock.ContextMenu>
<ContextMenu>
<MenuItem Command="{Binding VolumeTestCommand}"
Header="VolumeTest" />
</ContextMenu>
</TextBlock.ContextMenu>
</TextBlock>
</StackPanel>
</DataTemplate>
<HierachicalDataTemplate x:Key="ServerTemplate"
ItemsSource="{Binding Volumes}"
ItemTemplate="{StaticResource VolumeTemplate}">
<StackPanel Orientation="Horizontal">
<Image Source="{StaticResource ServerIcon}" Margin="3,3,3,3" />
<TextBlock Text="{Binding Name}" Margin="3,3,3,3" >
<TextBlock.ContextMenu>
<ContextMenu>
<MenuItem Command="{Binding ServerTestCommand}"
Header="ServerTest" />
</ContextMenu>
</TextBlock.ContextMenu>
</TextBlock>
</StackPanel>
</HierarchicalDataTemplate>
</Grid.Resources>
<TreeView HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
ItemsSource="{Binding Servers}" Name="tvMain"
ItemTemplate="{StaticResource ServerTemplate}"
PreviewMouseRightButtonDown="tvMain_PreviewMouseRightButtonDown" />
</Grid>
</Window>
和后面的代码:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Window_ContentRendered(object sender, EventArgs e)
{
//set DataContext here, based on a login dialog
}
static T VisualUpwardSearch<T>(DependencyObject source) where T : DependencyObject
{
DependencyObject returnVal = source;
while (returnVal != null && !(returnVal is T))
{
if (returnVal is Visual || returnVal is Visual3D)
{
returnVal = VisualTreeHelper.GetParent(returnVal);
}
else
{
returnVal = LogicalTreeHelper.GetParent(returnVal);
}
}
return returnVal as T;
}
private void tvMain_PreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
TreeViewItem treeViewItem = VisualUpwardSearch<TreeViewItem>(e.OriginalSource as DependencyObject);
if(treeViewItem != null)
{
treeViewItem.IsSelected = true;
e.Handled = true;
}
}
}
我尝试了引用问题的答案,但我认为它不起作用,因为上下文菜单位于 TextBlock 而不是 TreeViewItem 上。有没有办法将 ContextMenu 附加到 DataTemplate 中的 TreeViewItem,或者解决这个问题的另一种方法?