无法使用ItemContainerStyle为菜单项设置图标

时间:2011-06-24 07:53:50

标签: .net wpf xaml menuitem itemcontainerstyle

我正在设置像我这样的菜单项的图标 -

 <Grid>
    <Grid.Resources>
        <Image
              x:Key="ReportIconImage" Height="20" Width="20"
              Source="/Resource/flag.png"/>
        <Image
              x:Key="ReportIconImage1" Height="20" Width="20"
              Source="/Resource/flag.png"/>
    </Grid.Resources>
    <Menu Height="22" Margin="0,9,0,0" Name="menu1" VerticalAlignment="Top">
        <MenuItem Header="Menu">
            <MenuItem Header="Save" ></MenuItem>
            <MenuItem Header="Open"/>
            <MenuItem Header="Exit"/>
            <MenuItem.ItemContainerStyle>
                <Style TargetType="{x:Type MenuItem}">
                    <Setter  
                        Property="Icon" 
                        Value="{StaticResource ReportIconImage}">
                    </Setter>
                </Style>
            </MenuItem.ItemContainerStyle>
        </MenuItem>
        <MenuItem Header="Edit">
            <MenuItem Header="Undo"/>                   
            <MenuItem Header="Redo"/>                    
            <Separator/>
            <MenuItem Header="Cut"/>                    
            <MenuItem Header="Copy"/>                    
            <MenuItem  Header="Paste"/>
            <MenuItem.ItemContainerStyle>
                <Style TargetType="{x:Type MenuItem}">
                    <Setter  
                         Property="Icon" 
                         Value="{StaticResource ReportIconImage1}">
                </Setter>
                </Style>
            </MenuItem.ItemContainerStyle>
        </MenuItem>
    </Menu>
</Grid>

但仅显示最后一个菜单项的图标,而不是前两个。

enter image description here

示例应用程序 - http://weblogs.asp.net/blogs/akjoshi/Samples/WPFMenuItemBugSample.zip

任何人都可以提供此行为的原因以及可能的解决方案/解决方法。

3 个答案:

答案 0 :(得分:8)

这是因为您在资源中使用了ImageImage是一个控件,与任何其他控件一样,只能有一个父控件。默认情况下,WPF将尝试在所有使用者之间共享资源。因此,MenuItem和其他Image的最后MenuItem“赢得”托管权利甚至不允许在周末访问。

要解决此问题,您可以将Image设置为非共享:

<Image x:Shared="False" .../>

或者,更好的是,将您的图片资源显示为适当的ImageSource子类并分享:

<BitmapImage x:Key="ReportIconImage" Uri="/Resource/flag.png"/>
...
<Setter Property="Icon">
    <Setter.Value>
        <Image Source="{StaticResource ReportIconImage}"/>
    </Setter.Value>
</Setter>

答案 1 :(得分:5)

有点晚了,但这是一个对我有用的解决方案。

我使用转换器为每个菜单项创建一个新图像:

class PathToImageConverter:IValueConverter
{
    object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        string path = "Data/Icons/" + value + ".png";
        Image img = new Image {Source = new BitmapImage(new Uri(path, UriKind.Relative))};
        return img;
    }

    object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return "";
    }
}

的Xaml:

   <MenuItem.ItemContainerStyle>
        <Style TargetType="MenuItem">
            <Setter Property="Icon" Value="{Binding Converter={StaticResource PathToImageConverter1}}"/>
        </Style>
    </MenuItem.ItemContainerStyle>

答案 2 :(得分:0)

只是直接为每个菜单项添加一个图标属性,而不使用样式吗?也许我错过了一些东西,但这就是我在我的应用程序中所做的。

<Grid>
    <Menu Height="22" Margin="0,9,0,0" Name="menu1" VerticalAlignment="Top">
        <MenuItem Header="Menu">
            <MenuItem.Icon>
                <Image Height="20" Width="20" Source="/Resourceflag.png"/>
            </MenuItem.Icon>

            <MenuItem Header="Save" ></MenuItem>
            <MenuItem Header="Open"/>
            <MenuItem Header="Exit"/>
        </MenuItem>
        <MenuItem Header="Edit">
            <MenuItem.Icon>
                <Image Height="20" Width="20" Source="/Resourceflag.png"/>
            </MenuItem.Icon>

            <MenuItem Header="Undo"/>                   
            <MenuItem Header="Redo"/>                    
            <Separator/>
            <MenuItem Header="Cut"/>                    
            <MenuItem Header="Copy"/>                    
            <MenuItem  Header="Paste"/>
        </MenuItem>
    </Menu>
</Grid>