带图标的MenuItem样式只创建一个图标

时间:2011-05-30 14:30:52

标签: wpf mvvm

我在使用viewmodels作为ItemsSource的动态菜单渲染图标时出现问题 我在这里概述了我使用的解决方案 MVVM Dynamic Menu UI from binding with ViewModel

基本布局如下

<Grid>
  <Grid.Resources>
    <HierarchicalDataTemplate DataType="{x:Type ViewModels:HeaderedItemViewModel}"
        ItemsSource="{Binding Path=Children}">
      <ContentPresenter RecognizesAccessKey="True"></ContentPresenter>
    </HierarchicalDataTemplate>
    <Style TargetType="{x:Type MenuItem}">
      <Setter Property="Header" Value="{Binding Path=Header}" />
      <Setter Property="InputGestureText" Value="{Binding Path=InputGestureText}" />
      <Setter Property="Command" Value="{Binding Path=Command}" />
      <Setter Property="Icon">
        <Setter.Value>
          <Image Source="{Binding Path=Icon}" Height="16px" Width="16px" />
        </Setter.Value>
      </Setter>
    </Style>
  </Grid.Resources>
  <Menu Grid.Row="0" ItemsSource="{Binding Path=Shell.Navigation.Menus}" />
</Grid>

在上面的样式中,绑定'Icon'是'ImageSource'。设置如下。

        BitmapImage image = null;

        if (!string.IsNullOrEmpty(imagePath))
        {
            image = new BitmapImage(new Uri(imagePath, UriKind.Relative));
            image.CacheOption = BitmapCacheOption.OnLoad;
            image.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
        }
        var menu = new HeaderedItemViewModel
                       {
                           Header = header,
                           InputGestureText = inputGesture,
                           ImagePath = imagePath,
                           Icon = image,
                           Command = command,
                           IsEnabled = isEnabled
                       };

我遇到的问题是图标 似乎一次只会渲染一个图标?这是我的意思。

enter image description here

打开下拉菜单......

enter image description here

只要渲染了另一张图像,第一张图像就会消失?换句话说,只有最后一个图像是可见的。菜单中的所有图像都会发生这种情况。有什么想法吗?

2 个答案:

答案 0 :(得分:38)

为您的Icon值添加x:Shared = false。 要做到这一点,你应该在资源中声明Image:

<Grid>
  <Grid.Resources>

   <Image x:Key="imgCTX" x:Shared="false"
         Source="{Binding Path=Icon}" Height="16px" Width="16px"/>
    <HierarchicalDataTemplate DataType="{x:Type ViewModels:HeaderedItemViewModel}"
        ItemsSource="{Binding Path=Children}">
      <ContentPresenter RecognizesAccessKey="True"></ContentPresenter>
    </HierarchicalDataTemplate>
    <Style TargetType="{x:Type MenuItem}">
      <Setter Property="Header" Value="{Binding Path=Header}" />
      <Setter Property="InputGestureText" Value="{Binding Path=InputGestureText}" />
      <Setter Property="Command" Value="{Binding Path=Command}" />
      <Setter Property="Icon" Value="{StaticResource imgCTX}" />
    </Style>
  </Grid.Resources>
  <Menu Grid.Row="0" ItemsSource="{Binding Path=Shell.Navigation.Menus}" />
</Grid>

答案 1 :(得分:0)

我已经搜索了各种响应,并且x:Shared =“ false”确实可以帮助您,但是您还需要正确设置所有内容以确保其有效,并且花了我一些时间才能找到正确的解决方案。这就是我如何使之发挥作用的

        <ContextMenu ItemsSource="{Binding MenuElements}">
            <ContextMenu.Resources>
                <ControlTemplate x:Key="MenuSeparatorTemplate">
                    <Separator />
                </ControlTemplate>
                <Image
                    x:Key="MenuIcon"
                    Width="16"
                    Height="16"
                    x:Shared="False"
                    Source="{Binding Icon}" />
            </ContextMenu.Resources>
            <ContextMenu.ItemContainerStyle>
                <Style TargetType="{x:Type MenuItem}">
                    <Setter Property="Header" Value="{Binding Name}" />
                    <Setter Property="ItemsSource" Value="{Binding Childs}" />
                    <Setter Property="Command" Value="{Binding Run}" />
                    <Setter Property="Icon" Value="{StaticResource MenuIcon}" />
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding IsSeparator}" Value="true">
                            <Setter Property="Template" Value="{StaticResource MenuSeparatorTemplate}" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </ContextMenu.ItemContainerStyle>
        </ContextMenu>

通过这种方式,我可以使上下文菜单根据输入动态加载图标。