Home Dashboard Directory Help

WPF MenuItem.Icon cannot be set via setter. by Shimmy Weitzhandler


Status: 

Active


22
0
Sign in
to vote
Type: Bug
ID: 497408
Opened: 10/12/2009 1:20:36 PM
Access Restriction: Public
4
Workaround(s)
view
13
User(s) can reproduce this bug

Description

<Application.Resources>            
         <Style x:Key="MenuItem_Edit" TargetType="MenuItem" BasedOn="{StaticResource {x:Type MenuItem}}">
                <Setter Property="MenuItem.Header" Value="_Edit"/>
                <Setter Property="Icon">
                    <Setter.Value>
                        <Image Source="Resources\edit.png"/>
                    </Setter.Value>
                </Setter>
            </Style>
</Application.Resources>

Then
<Window>
    <ContextMenu>
        <MenuItem Style="{StaticResource MenuItem_Edit}" />
    </ContextMenu>
</Window>

Doesn't work.
Details
Sign in to post a comment.
Posted by Will Sullivan on 10/22/2010 at 6:23 AM
I think the real bug here is that apparently Styles are unaware of LSP.
Posted by Shimmy Weitzhandler on 10/21/2010 at 5:32 PM
I reopened the connection.
Posted by Kris Mackintosh on 8/12/2010 at 12:44 PM
If its fixed in 4.0 then its obviously not "AS BY DESIGN", thats like putting your fingers in your ears and saying LA LA LA LA, i cant hear you!
Posted by Shimmy Weitzhandler on 7/21/2010 at 11:59 AM
I think once they close an event as By Design, all the following comments are ignored.
Posted by Karl-Michael Beck on 7/21/2010 at 5:23 AM
The workaround isn't suitable for me because i cannot use a static resource.

I don't understand what microsoft did here...
It's just i have an object (Image/ImageSource) i want to assign to a property. Exactly this object without any uri-conversion or something.

It's really to bad what is done here starting from the point where ItemCOntainerSTyle property is used instead the user can instantiate his menuitem on his own. I had to completely change the syntax to use setters and now i recognize that fundamental things simply don't work with it.
Posted by Nicolas Séveno on 4/15/2010 at 3:37 AM
I can reproduce it in a slightly different way.

On a Window, put the following code :

<Menu Height="23"
             VerticalAlignment="Top">
            <MenuItem Header="Test"
                     ItemsSource="{StaticResource CommandItems}">
                <MenuItem.ItemContainerStyle>
                    <Style TargetType="{x:Type MenuItem}"
                         BasedOn="{StaticResource {x:Type MenuItem}}">
                        <Setter Property="MenuItem.Header"
                                Value="Blah" />
                        <Setter Property="MenuItem.Icon">
                            <Setter.Value>
                                <Image Source="/TestsGrid;component/Resources/BarCodeHS.png" />
                            </Setter.Value>
                        </Setter>
                    </Style>
                </MenuItem.ItemContainerStyle>
            </MenuItem>
        </Menu>

==> Only the last icon is visible !!!
Posted by Mike Danes on 2/23/2010 at 1:55 AM
The above example works fine in .NET 4 RC so I guess this has been fixed.

"What if I want to dynamically build a Menu using the MVVM design pattern? Cannot reasonably define the images for the MenuItems."

Sure you can. Bind the Icon property to a string/Uri property and use a ValueConverter to convert the string/Uri to an Image object. It's not ideal because a new Image object is generated every time the binding is updated but it works fine. Of course, since in .NET 4 the above problem has been fixed you don't need this anymore.
Posted by Greg Shaffer on 2/4/2010 at 12:36 PM
There doesn't appear to be any reasonable way to Bind an image for a MenuItem from within a Style that has a TargetType of MenuItem. The only technique I've found is to define an entire ControlTemplate for the MenuItem. This is really, really bad. What if I want to dynamically build a Menu using the MVVM design pattern? Cannot reasonably define the images for the MenuItems.
Posted by Shimmy Weitzhandler on 11/9/2009 at 12:14 PM
I still don't understand why this is CLOSED as by design
Posted by Shimmy Weitzhandler on 11/3/2009 at 1:48 AM
In other words I tried what you said and it doesn't work.
Posted by Shimmy Weitzhandler on 11/3/2009 at 1:47 AM
I attached a photo that shows what happens when I do what you said.
Posted by jods on 10/21/2009 at 3:07 PM
If the issue is the same as Window.icon, you should try not to pass an image but just your Uri.
That is, maybe the following code works:
<Setter Property="Icon" Value="Resources\edit.png" />
Posted by Shimmy Weitzhandler on 10/17/2009 at 9:23 AM
Hello!?!?
Posted by Shimmy Weitzhandler on 10/15/2009 at 6:23 PM
Why did you mark it as resolved???
Posted by Microsoft on 10/14/2009 at 10:29 PM
Thanks for your feedback. We are routing this bug to the product unit who works on that specific feature area. The team will review this issue and make a decision on whether they will fix it or not for the next release.

Thank you,
Visual Studio Product Team
Sign in to post a workaround.
Posted by derwochi on 4/4/2012 at 3:44 AM
complete markup as suggested by Nicolas Séveno

    <UserControl.Resources>
        <Image x:Key="_menuItemImage"
             x:Shared="False"
             Source="{Binding SmallImage}" />
        <Style x:Key="_menuItemStyle"
             TargetType="{x:Type MenuItem}"
             BasedOn="{StaticResource {x:Type MenuItem}}">
            <Setter Property="Header"
                    Value="{Binding Text}" />
            <Setter Property="Icon"
                    Value="{StaticResource _menuItemImage}" />
            <Setter Property="Command"
                    Value="{Binding Command}" />
        </Style>
    </UserControl.Resources>
Posted by roeeoz on 3/31/2011 at 8:46 AM
Based on the previous example, but with mvvm, style and data bindings


    <Image
        x:Key="img"
        x:Shared="False"
        Source="{Binding Icon}"
        DataContext="{Binding DataContext,
            RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type telerik:RadMenuItem}}}"
        />

    <Style
        x:Key="{ComponentResourceKey TypeInTargetAssembly={x:Type local:Resources}, ResourceId=MenuItemStyle}"
        TargetType="telerik:RadMenuItem"
        >
        <Setter Property="Command" Value="{Binding Command}"></Setter>
        <Setter Property="ItemsSource" Value="{Binding Children}"></Setter>
        <Setter Property="Icon" Value="{StaticResource img}">
        </Setter>

    </Style>

Roee
Posted by Shimmy Weitzhandler on 12/26/2010 at 11:50 PM
View

http://stackoverflow.com/questions/30239/wpf-setting-a-menuitem-icon-in-code

for some options
Posted by Nicolas Séveno on 4/15/2010 at 5:50 AM
I finally found a workaround here :

http://www.julmar.com/blog/mark/2009/04/29/MenusAndMVVM2.aspx

The solution is to put the image in a resource dictionary and mark it as non shared.
Here is a sample that worked for me :

        <Menu Height="23"
             VerticalAlignment="Top">            
            <Menu.Resources>
                <Image x:Key="img"
                     x:Shared="False"
                     Source="BarCodeHS.png"
                     Width="16" />
            </Menu.Resources>            
            <MenuItem Header="Test">
                <MenuItem.Items>
                    <MenuItem />
                    <MenuItem />
                    <MenuItem />
                </MenuItem.Items>
                <MenuItem.ItemContainerStyle>
                    <Style TargetType="{x:Type MenuItem}"
                         BasedOn="{StaticResource {x:Type MenuItem}}">
                        <Setter Property="MenuItem.Header"
                                Value="Blah" />
                        <Setter Property="MenuItem.Icon"
                                Value="{StaticResource img}" />
                    </Style>
                </MenuItem.ItemContainerStyle>
            </MenuItem>
        </Menu>

==> The three icons are visible.