继上一个问题here之后,我正在努力为MenuItem
Icon
设置一个控件,我根据字符串依赖属性插入图标图像。
最初我开始时:
<ContextMenu ItemsSource="{Binding MenuItems}">
<ContextMenu.Resources>
<Style TargetType="MenuItem">
...
<Setter Property="Icon">
<local:StringToIcon IconName="{Binding IconName}" />
</Setter>
</Style>
</ContextMenu.Resources>
</ContextMenu>
这具有可预测的效果,即只显示菜单中的一个图标,通常是最后一个,因为实例是共享的。
然后我尝试了非共享资源方法:
<ContextMenu ItemsSource="{Binding MenuItems}">
<ContextMenu.Resources>
<local:StringToIcon x:Key="MenuIcon" x:Shared="False" IconName="{Binding IconName}" />
<Style TargetType="MenuItem">
...
<Setter Property="Icon" Value="{StaticResource MenuIcon} />
</Style>
</ContextMenu.Resources>
</ContextMenu>
这没有效果。它没有在Intellisense中提供x:Shared
,所以我想知道这是否是一个无效的属性。
出于绝望,我把东西扔进模板:
<Setter Property="Icon">
<Setter.Value>
<ContentControl>
<ContentControl.Template>
<ControlTemplate>
<local:StringToIcon IconName="{Binding IconName}" />
</ControlTemplate>
</ContentControl.Template>
</ContentControl>
</Setter.Value>
</Setter>
再一次,没有效果。我的StringToIcon
目前看起来像这样,用单个图像进行硬编码以检查问题是否存在。 (或者是吗?)
<UserControl x:Class="RAP.Admin3.Components.StringToIcon"
...
>
<Image DataContext="{Binding ElementName=StringIconControl}" Source="pack://application:,,,/Resources/Icons/lorry.png"/>
</UserControl>
如何将这个令人难忘的东西送到模板并允许多次使用?这可能是我忽视的基本内容。
我查看了各种类似的问题,而且大多数似乎都使用非共享资源方法取得了成功。
修改:让我按要求添加更多代码。我想出了一个问题的最小复制:
上下文菜单是TreeView资源的一部分。
<UserControl x:Class="MyApp.ItemHierarchy"
...
Name="ItemHierarchyControl">
<Grid>
<TreeView ItemsSource="{Binding ElementName=ItemHierarchyControl, Path=Items}">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type local:HierarchyItem}" ItemsSource="{Binding Subitems}">
<StackPanel Orientation="Horizontal" Margin="0,1,4,1">
<TextBlock Text="My text" VerticalAlignment="Center" />
<StackPanel.ContextMenu>
<ContextMenu ItemsSource="{Binding MenuItems}">
<ContextMenu.Resources>
<local:StringToIcon x:Key="MenuIcon" x:Shared="False" IconName="{Binding IconName}" />
<Style TargetType="MenuItem">
<Setter Property="Header" Value="{Binding Path=Name}" />
<Setter Property="Icon" Value="{StaticResource MenuIcon}" />
</Style>
</ContextMenu.Resources>
</ContextMenu>
</StackPanel.ContextMenu>
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
</Grid>
</UserControl>
这由项目的依赖项属性支持。
public ObservableCollection<HierarchyItem> Items
{
get { return (ObservableCollection<HierarchyItem>)GetValue(ItemsProperty); }
set { SetValue(ItemsProperty, value); }
}
public static readonly DependencyProperty ItemsProperty = DependencyProperty.Register("Items", typeof(ObservableCollection<HierarchyItem>), typeof(ItemHierarchy), new PropertyMetadata(new ObservableCollection<HierarchyItem>()));
StringToIcon
也受到图标名称的字符串依赖项属性的支持,由于目前硬编码的图像,该属性会被忽略。
HierarchyItem
对于示例很简单:
public ObservableCollection<HierarchyItem> Subitems { get; set; }
public ObservableCollection<BindableMenuItem> MenuItems { get; set; }
为了使这个证明有效,我将ItemHierarchy
附加到主窗口的某些属性:
public ObservableCollection<BindableMenuItem> MenuItems { get; set; }
public ObservableCollection<HierarchyItem> IHItems { get; set; }
public MainWindow()
{
MenuItems = new ObservableCollection<BindableMenuItem>();
MenuItems.Add(new BindableMenuItem("Item", null));
MenuItems.Add(new BindableMenuItem("Item", null));
MenuItems.Add(new BindableMenuItem("Item", null));
MenuItems.Add(new BindableMenuItem("Item", null));
IHItems = new ObservableCollection<HierarchyItem>();
IHItems.Add(new HierarchyItem() { MenuItems = this.MenuItems });
InitializeComponent();
}
编辑2:此处BindableMenuItem
也是:
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; }
}
答案 0 :(得分:1)
尝试将StringToIcon
移至<TreeView.Resources>
:
<TreeView ItemsSource="{Binding ElementName=ItemHierarchyControl, Path=Items}">
<TreeView.Resources>
<local:StringToIcon x:Key="MenuIcon" x:Shared="False" IconName="{Binding IconName}" />
<HierarchicalDataTemplate DataType="{x:Type local:HierarchyItem}" ItemsSource="{Binding Subitems}">
<StackPanel Orientation="Horizontal" Margin="0,1,4,1">
<TextBlock Text="My text" VerticalAlignment="Center" />
<StackPanel.ContextMenu>
<ContextMenu ItemsSource="{Binding MenuItems}">
<ContextMenu.Resources>
<Style TargetType="MenuItem">
<Setter Property="Header" Value="{Binding Path=Name}" />
<Setter Property="Icon" Value="{StaticResource MenuIcon}" />
</Style>
</ContextMenu.Resources>
</ContextMenu>
</StackPanel.ContextMenu>
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>