在WPF中的整个TreeViewItem行上显示上下文菜单
我有一个具有异构节点类型的树视图。使用HierarchycalDataTemplate在XAML中配置每个节点类型 某些节点具有上下文菜单,这取决于节点的类型。ContextMenus在XAML中定义为静态资源,并附加到HierarchycalDataTemplate中的DockPanel 此外,我正在为bendewey在下面的StackOverflow问题中描述的TreeView项目使用ControlTemplate。此ControlTemplate的定义是为了在选中时高亮显示完整的TreeViewItem。 在该行的任何部分上单击鼠标左键,即可选择该项目 相反,在HierarchycalDataTemplate中定义的上下文菜单仅在行的右侧部分起作用 我正在寻找一种方法来配置ContextMenus,以便它们也可以在完整的行中使用 这似乎需要将上下文菜单附加到ControlTemplate中的元素,并将TemplateBinding绑定到HierarchycalDataTemplate中定义的内容,但我不知道如何执行此操作在WPF中的整个TreeViewItem行上显示上下文菜单,wpf,xaml,templates,contextmenu,treeviewitem,Wpf,Xaml,Templates,Contextmenu,Treeviewitem,我有一个具有异构节点类型的树视图。使用HierarchycalDataTemplate在XAML中配置每个节点类型 某些节点具有上下文菜单,这取决于节点的类型。ContextMenus在XAML中定义为静态资源,并附加到HierarchycalDataTemplate中的DockPanel 此外,我正在为bendewey在下面的StackOverflow问题中描述的TreeView项目使用ControlTemplate。此ControlTemplate的定义是为了在选中时高亮显示完整的TreeV
顺便说一句,VisualStudio中的解决方案资源管理器正好具有这种行为。上下文菜单取决于节点类型,在完整项上可用,包括展开/折叠按钮的左侧。编辑您需要以树状项样式删除网格的两列: 请注意,您应调整转换器,以考虑所需的额外裕度:
public class LeftMarginMultiplierConverter : IValueConverter
{
public double Length { get; set; }
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var item = value as TreeViewItem;
if (item == null)
return new Thickness(0);
int extra = int.Parse(parameter.ToString());
var t = item.GetDepth();
return new Thickness(Length * (item.GetDepth() + extra), 0, 0, 0);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new System.NotImplementedException();
}
}
如果converter参数为1,它将向项目的深度添加一个点。我用它作为标题部分
另一种方法可能是向TreeViewItem样式的ContentPresenter添加数据模板。虽然我不知道如何绑定ContextMenu,但我更喜欢这个 这不是问题所在。TreeViewItem的ControlTemplate根据树的深度定义边距,然后是展开/折叠按钮,然后是数据模板所在的ContentPresenter。我希望整行都有上下文菜单,因此它需要在ControlTemplate中的边框、网格或某些新元素上定义,但要绑定到HierarchycalDataTemplate中的定义。谢谢,这很有效。对于将缩进的责任向下转移到DataTemplates和HierarchycalDataTemplates中,我有一点不好的感觉。我的直觉反应是它不属于那里。但是,您可能会争辩说ContextMenu也不属于该行的这一部分。
<TreeView Margin="50" HorizontalContentAlignment="Stretch" DataContext="{Binding}" ItemsSource="{Binding Models}">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate DataType="{x:Type local:Model}" ItemsSource="{Binding Models}">
<Border Background="Transparent">
<TextBlock Margin="{Binding Converter={StaticResource lengthConverter}, ConverterParameter=1,
RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=TreeViewItem}}"
Text="{Binding Name}" />
<Border.ContextMenu>
<ContextMenu>
<MenuItem Header="dddd"/>
</ContextMenu>
</Border.ContextMenu>
</Border>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
public class LeftMarginMultiplierConverter : IValueConverter
{
public double Length { get; set; }
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var item = value as TreeViewItem;
if (item == null)
return new Thickness(0);
int extra = int.Parse(parameter.ToString());
var t = item.GetDepth();
return new Thickness(Length * (item.GetDepth() + extra), 0, 0, 0);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new System.NotImplementedException();
}
}