0

I using this solution in order to bind my Menu just like at this example and I wonder how can I add icon to my MenuItem.

In my Model I also have property called IsSelected so I try this approach:

<Menu.ItemTemplate>
      <HierarchicalDataTemplate DataType="{x:Type Menu:MenuItemViewModel}" ItemsSource="{Binding Path=MenuItems}">
      <StackPanel Orientation="Horizontal">
         <Image Source="pack://application:,,,/Resources/checked_lightslategray.ico"
                Width="12"
                Height="12"
                Margin="0,0,0,0">
                <Image.Style>
                    <Style TargetType="Image">
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding Path=IsSelected}" Value="True">
                                   <Setter Property="Visibility" Value="Visible"/>
                            </DataTrigger>
                            <DataTrigger Binding="{Binding Path=IsSelected}" Value="False">
                                    <Setter Property="Visibility" Value="Collapsed"/>
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </Image.Style>
            </Image>
        <TextBlock Text="{Binding Description}" Margin="10,0,0,0"/>
        </StackPanel>
    </HierarchicalDataTemplate>
</Menu.ItemTemplate>

But this looks bad as you can see:

enter image description here

Any ideas how to move this image to the icon place on the left side of my MenuItem ?

Edit

This is the style i am using:

<Style TargetType="{x:Type Menu}" x:Key="StandardMenu">
        <Style.Resources>
            <Style x:Key="{x:Static MenuItem.SeparatorStyleKey}" TargetType="Separator">
                <Setter Property="Height" Value="1"/>
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="Separator">
                            <Border BorderBrush="{StaticResource MenuSeparatorBorderBrush}" BorderThickness="1" Margin="25,0,0,0"/>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
            <Style TargetType="{x:Type MenuItem}">
                <Setter Property="Foreground" Value="{Binding Path=Foreground, RelativeSource={RelativeSource AncestorType={x:Type Menu}}}"/>
                <Setter Property="FontSize" Value="{DynamicResource ApplicationFontSize}"/>
                <Setter Property="Command" Value="{Binding Command}"/>
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type MenuItem}">
                            <!--Border 1-->
                            <Border x:Name="Border" Background="Transparent" BorderBrush="Transparent"  CornerRadius="2"
                                    BorderThickness="1" SnapsToDevicePixels="False">
                                <Grid x:Name="Grid">
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition x:Name="Col0" MinWidth="17" Width="Auto" SharedSizeGroup="MenuItemIconColumnGroup"/>
                                        <ColumnDefinition Width="Auto" SharedSizeGroup="MenuTextColumnGroup"/>
                                        <ColumnDefinition Width="Auto" SharedSizeGroup="MenuItemIGTColumnGroup"/>
                                        <ColumnDefinition x:Name="Col3" Width="14"/>
                                    </Grid.ColumnDefinitions>
                                    <ContentPresenter Grid.Column="0" x:Name="Icon" VerticalAlignment="Center" ContentSource="Icon"/>
                                    <ContentPresenter Grid.Column="1" Margin="{TemplateBinding Padding}" x:Name="HeaderHost" RecognizesAccessKey="True" ContentSource="Header" VerticalAlignment="Center"/>
                                    <ContentPresenter Grid.Column="2" Margin="8,1,8,1" x:Name="IGTHost" ContentSource="InputGestureText" VerticalAlignment="Center"/>
                                    <Grid Grid.Column="3" Margin="4,0,6,0" x:Name="ArrowPanel" VerticalAlignment="Center">
                                        <Path x:Name="ArrowPanelPath" HorizontalAlignment="Right" VerticalAlignment="Center" Fill="{TemplateBinding Foreground}" Data="M0,0 L0,8 L4,4 z"/>
                                    </Grid>
                                    <Popup IsOpen="{Binding Path=IsSubmenuOpen, RelativeSource={RelativeSource TemplatedParent}}" 
                                           Placement="Right"
                                           HorizontalOffset="-1" 
                                           x:Name="SubMenuPopup"
                                           Focusable="false"
                                           PopupAnimation="{DynamicResource {x:Static SystemParameters.MenuPopupAnimationKey}}"
                                           AllowsTransparency="True">
                                        <Grid Margin="0,0,5,5">
                                            <!--Border 2-->
                                            <Border x:Name="SubMenuBorder" CornerRadius="5"
                                                    BorderBrush="{StaticResource MenuSeparatorBorderBrush}"
                                                    BorderThickness="1" 
                                                    Background="{StaticResource SubmenuItemBackground}" 
                                                    SnapsToDevicePixels="True">
                                                <Grid x:Name="SubMenu" Grid.IsSharedSizeScope="True" Margin="2">
                                                    <StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Cycle"/>
                                                </Grid>
                                                <Border.Effect>
                                                    <DropShadowEffect ShadowDepth="2" Color="Black"/>
                                                </Border.Effect>
                                            </Border>
                                            <!--Border 3-->
                                            <Border Margin="1,0,0,0"
                                                    x:Name="TransitionBorder"
                                                    Width="0" 
                                                    Height="2" 
                                                    VerticalAlignment="Top"
                                                    HorizontalAlignment="Left" 
                                                    Background="{StaticResource SubmenuItemBackground}"
                                                    SnapsToDevicePixels="False"
                                                    BorderThickness="1" 
                                                    BorderBrush="{StaticResource SubmenuItemBackground}"/>
                                        </Grid>
                                    </Popup>
                                </Grid>
                            </Border>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </Style.Resources>
        <Setter Property="Background" Value="{StaticResource LightBackground}"/>
        <Setter Property="Foreground" Value="{StaticResource Foreground}"/>
    </Style>
Clemens
  • 123,504
  • 12
  • 155
  • 268
falukky
  • 1,099
  • 2
  • 14
  • 34

2 Answers2

1

on image style trigger, you have set image visibility to collapsed which will release space required for the image and content will move to the left when there is no image visible.

there are two approaches to overcome this.

Option 1: instead of visibility as Collapsed, go for visibility as Hidden.

<Menu.ItemTemplate>
      <HierarchicalDataTemplate DataType="{x:Type Menu:MenuItemViewModel}" ItemsSource="{Binding Path=MenuItems}">
      <StackPanel Orientation="Horizontal">
         <Image Source="pack://application:,,,/Resources/checked_lightslategray.ico"
                Width="12"
                Height="12"
                Margin="0,0,0,0">
                <Image.Style>
                    <Style TargetType="Image">
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding Path=IsSelected}" Value="True">
                                   <Setter Property="Visibility" Value="Visible"/>
                            </DataTrigger>
                            <DataTrigger Binding="{Binding Path=IsSelected}" Value="False">
                                    <Setter Property="Visibility" Value="Hidden"/>
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </Image.Style>
            </Image>
        <TextBlock Text="{Binding Description}" Margin="10,0,0,0"/>
        </StackPanel>
    </HierarchicalDataTemplate>
</Menu.ItemTemplate>

Option 2: - Use Header attribute to define your Description - Use to define your image

<HierarchicalDataTemplate  ItemsSource="{Binding Path=MenuItems}">
                        <MenuItem Header="{Binding Header}" ItemsSource="{Binding Path=MenuItems}" FontWeight="Bold">
                            <MenuItem.Icon>
                                <Image Source="pack://application:,,,/Resources/checked_lightslategray.ico">
                                    <Image.Style>
                                        <Style TargetType="Image">
                                            <Style.Triggers>
                                                <DataTrigger Binding="{Binding Path=IsSelected}" Value="True">
                                                    <Setter Property="Visibility" Value="Visible"/>
                                                </DataTrigger>
                                                <DataTrigger Binding="{Binding Path=IsSelected}" Value="False">
                                                    <Setter Property="Visibility" Value="Collapsed"/>
                                                </DataTrigger>
                                            </Style.Triggers>
                                        </Style>
                                    </Image.Style>
                                </Image>
                            </MenuItem.Icon>
                            <MenuItem.ItemsPanel>
                                <ItemsPanelTemplate>
                                    <VirtualizingStackPanel Orientation="Horizontal"/>
                                </ItemsPanelTemplate>
                            </MenuItem.ItemsPanel>
                        </MenuItem>
                    </HierarchicalDataTemplate>
maulik kansara
  • 1,087
  • 6
  • 21
  • Is it possible to locate the image on the left side where the icon should place ? – falukky Jul 05 '18 at 11:51
  • have you tried adding path of an image instead of icon as you have added? – maulik kansara Jul 06 '18 at 11:15
  • Because i am using style i think need to add the Menu.Resources into my style, i try to do so but unfortunately i do not know where, please see my update, i added the style i am using, can you show me please where i need to put this Menu.Resources code ? – falukky Jul 07 '18 at 06:49
  • you should add Menu.Resources just under tag located in second line. – maulik kansara Jul 07 '18 at 11:23
1

Put this to your Menu.Resources and delete Image from StackPanel:

<Menu.Resources>
    <Image x:Key="img" x:Shared="false" Source="pack://application:,,,/Resources/checked_lightslategray.ico"/>
    <Style TargetType="MenuItem">
        <Style.Triggers>
            <DataTrigger Binding="{Binding IsSelected}" Value="true">
                <Setter Property="Icon" Value="{StaticResource img}"/>
            </DataTrigger>
        </Style.Triggers>
    </Style>
</Menu.Resources>
Rekshino
  • 6,954
  • 2
  • 19
  • 44
  • Because i am using style i think need to add the Menu.Resources into my style, i try to do so but unfortunately i do not know where, please see my update, i added the style i am using, can you show me please where i need to put your code ? – falukky Jul 06 '18 at 15:05