简体   繁体   中英

Unable to set icon for the menu item using ItemContainerStyle

I am trying to set the Icon of my menu item like this -

 <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>

but the icon for only last menu item is displayed and not for first two.

在此输入图像描述

Sample application - http://weblogs.asp.net/blogs/akjoshi/Samples/WPFMenuItemBugSample.zip

Can anyone provide the reason for this behavior and possible solutions/workarounds.

It's because you've used an Image in your resources. An Image is a control and - like any other control - can only have one parent. By default, WPF will attempt to share resources across all consumers. Thus, the last MenuItem "wins" custodial rights to the Image and the other MenuItem 's aren't even allowed weekend visitations.

To rectify this, you could either set the Image to be non-shared:

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

Or, better still, manifest your image resource as the appropriate ImageSource subclass and share that instead:

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

A little late, but here is a solution that worked for me.

I used a converter to make a new image for each menuitem:

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>

Would it work to just add an icon property to each menu item directly, without using a style? Maybe I'm missing something, but this is what I've done in my apps.

<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>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM