在TreeView
资源中,我有一个HierarchicalDataTemplate
,它还定义了上下文菜单样式。目的是能够以编程方式定义MenuItem
指定图标名称为Tag
,然后让前端显示正确的图标。
<StackPanel.ContextMenu>
<ContextMenu ItemsSource="{Binding MenuItems}">
<ContextMenu.Resources>
<Style TargetType="{x:Type MenuItem}">
<Setter Property="Icon">
<Setter.Value>
<local:StringToIcon IconName="{Binding Tag, RelativeSource={RelativeSource AncestorType=MenuItem}}" />
</Setter.Value>
</Setter>
</Style>
</ContextMenu.Resources>
</ContextMenu>
</StackPanel.ContextMenu>
StringToIcon
是另一个控件,用于测试,看起来就像这样。它由依赖属性IconName
支持。
<UserControl x:Class="MyApp.Components.StringToIcon"
...
Name="StringIconControl">
<Image DataContext="{Binding ElementName=StringIconControl}">
<Image.Style>
<Style TargetType="{x:Type Image}">
<Style.Triggers>
<DataTrigger Binding="{Binding IconName}" Value="Refresh">
<Setter Property="Source" Value="{StaticResource IconRefresh}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
</UserControl>
IconRefresh
只是一个全球可用的资源:
<BitmapImage x:Shared="False" x:Key="IconRefresh" UriSource="pack://application:,,,/Resources/Icons/refresh.png" />
启动应用程序时,不会显示任何上下文菜单刷新图标。他们都是空白的。我遇到了绑定错误,我认为这是因为上下文菜单不在可视化树中:
无法找到使用引用绑定的来源&#39; RelativeSource FindAncestor,AncestorType =&#39; System.Windows.Controls.MenuItem&#39;,AncestorLevel =&#39; 1&#39;&#39;。 BindingExpression:路径=标签;的DataItem = NULL;目标元素是&#39; StringToIcon&#39; (名称=&#39; StringIconControl&#39);目标属性是&#39; IconName&#39; (键入&#39; String&#39;)
但是,使用Snoop检查菜单时,所有绑定和依赖项属性都是正确的。在以这种方式检查之后,奇迹般地检查了刷新图标,好像它强迫绑定重新评估。您可以逐个对此图标的每个实例执行此操作,并且它们会出现。
如何解决这里似乎发生的这种懒惰绑定?或者还有别的东西在玩吗?我看到另一篇文章建议将菜单数据上下文附加到可视树中 的内容,但我不知道在这个实例中会出现什么。
答案 0 :(得分:0)
绑定问题的最终解决方案是创建一个新类来保存菜单项详细信息:
public class BindableMenuItem
{
public BindableMenuItem(string name, ICommand command)
{
this.Name = name;
this.Command = command;
}
public string Name { get; set; }
public ICommand Command { get; set; }
public string IconName { get; set; }
public ObservableCollection<BindableMenuItem> Children { get; set; }
}
然后将其与菜单项的样式联系起来,如下所示:
<Style TargetType="MenuItem">
<Setter Property="Header" Value="{Binding Name}" />
<Setter Property="Command" Value="{Binding Command}" />
<Setter Property="ItemsSource" Value="{Binding Children}" />
<Setter Property="Icon">
<Setter.Value>
<local:StringToIcon IconName="{Binding IconName}" />
</Setter.Value>
</Setter>
</Style>
可能这是有效的,因为绑定不依赖于可视化树中存在相对源,而是具有要使用的具体模型类。
但是,对于多个样式实例,上述问题仍然存在问题。我将发布另一个问题。