この質問と同じ問題があります。コンテキストメニューが表示されているときに、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;
}
}
}
参照された質問からの回答を試しましたが、コンテキストメニューがTreeViewItemではなくTextBlockにあるため、機能しないと思います。DataTemplateのTreeViewItemにContextMenuをアタッチする方法、またはこの問題に対処する別の方法はありますか?