2011-06-24 13 views
5

Estoy tratando de establecer el icono de mi elemento de menú como este -No se puede establecer icono para el elemento de menú con 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> 

pero se muestra el icono por sólo último elemento del menú y no para dos primeros.

enter image description here

aplicación de la muestra - http://weblogs.asp.net/blogs/akjoshi/Samples/WPFMenuItemBugSample.zip

¿Puede cualquier persona proporcionar la razón de este comportamiento y posibles soluciones/soluciones.

Respuesta

8

Es porque usted ha utilizado un Image en sus recursos. Un Image es un control y, como cualquier otro control, solo puede tener un padre. Por defecto, WPF intentará compartir recursos entre todos los consumidores. Por lo tanto, los últimos MenuItem "gana" derechos de custodia a la Image y los otros MenuItem 's no se les permite visitas de fin de semana.

Para rectificar esto, se podía o bien establecer el Image ser no compartida:

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

O, mejor aún, manifestar su recurso de imagen como el ImageSource subclase apropiada y la cuota que en lugar:

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

Gracias Kent, pero por desgracia tanto las soluciones no funciona. No hay impacto de primero y segundo genera después de la excepción: - No se puede agregar contenido de tipo 'System.Windows.Controls.Image' a un objeto de tipo 'System.Object'. Error en el objeto 'System.Windows.Controls.Image' en el archivo de marcado 'Sample; component/window1.xaml' Line 27 Position 34. – akjoshi

+0

En caso de que ayude, he cargado la aplicación de muestra que reproduce este problema en la pregunta; – akjoshi

+2

@akjoshi: gracias por la reproducción. Cambiar mi proyecto a WPF 4 permite que mi primera sugerencia funcione, por lo que debe haber un error en 3.5. En cuanto a mi segunda sugerencia, eso no funcionará porque WPF está intentando utilizar la misma imagen en todos los artículos de menú, de la manera que describí en mi respuesta. Si hubiera una propiedad 'IconTemplate', la usarías. Desafortunadamente, 'MenuItem' no es lo suficientemente fino como para tener uno, por lo que solo puedo sugerir reemplazar el' Template'. Frustrante por decir lo menos. –

0

¿Funcionaría simplemente agregar una propiedad de icono a cada elemento de menú directamente, sin usar un estilo? Tal vez me falta algo, pero esto es lo que hice en mis aplicaciones.

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

Un poco tarde, pero he aquí una solución que funcionó para mí.

que utiliza un convertidor para hacer una nueva imagen para cada elemento de menú:

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

Esto funcionó muy bien en un escenario específico, gracias. –

Cuestiones relacionadas