2011-06-24 12 views
5

Próbuję ustawić Ikona mojego menu tak -Nie można ustawić ikonę menu używając 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> 

ale ikona jest wyświetlana tylko dla ostatniej pozycji menu, a nie do dwóch pierwszych.

enter image description here

Przykładowa aplikacja - http://weblogs.asp.net/blogs/akjoshi/Samples/WPFMenuItemBugSample.zip

Może ktoś podać przyczynę tego problemu i możliwych rozwiązań/obejścia.

Odpowiedz

8

To dlatego, że użyłeś Image w swoich zasobach. An Image to kontrola i - jak każda inna kontrola - może mieć tylko jednego rodzica. Domyślnie WPF będzie próbować udostępniać zasoby wszystkim klientom. Tak więc ostatnie MenuItem "wygrywa" prawa do zatrzymania do Image i innych MenuItem 's nie są dozwolone nawet w weekendy.

Aby to naprawić, można też ustawić Image być niewspólną:

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

Albo, jeszcze lepiej, manifestują swoje źródło obrazu jako odpowiedniej ImageSource podklasy i akcję, która w zamian:

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

Thanks Kent, ale niestety oba rozwiązania nie działa. Nie ma wpływu pierwszego, a drugi generuje następujący wyjątek: - Nie można dodać zawartości typu "System.Windows.Controls.Image" do obiektu typu "System.Object". Błąd w obiekcie "System.Windows.Controls.Image" w pliku znaczników "Próbka; komponent/okno1.xaml" Wiersz 27 Pozycja 34. – akjoshi

+0

Jeśli to pomaga, załadowałem przykładową aplikację odtwarzającą ten problem w pytaniu; – akjoshi

+2

@akjoshi: dzięki za repro. Przełączenie projektu na WPF 4 pozwala mojej pierwszej sugestii działać, więc w wersji 3.5 musi występować błąd. Co do mojej drugiej sugestii, to nie zadziała, ponieważ WPF próbuje użyć tego samego Obrazu we wszystkich MenuItems, w sposób opisany w mojej odpowiedzi. Jeśli istniała własność 'IconTemplate', używałbyś tego. Niestety, 'MenuItem' nie jest wystarczająco drobnoziarnista, aby je mieć, więc mogę tylko zasugerować zastąpienie' Szablonu' zamiast tego. Co najmniej frustrujące. –

0

Czy to wystarczy, aby dodać właściwość ikony do każdego elementu menu bezpośrednio, bez używania stylu? Może czegoś brakuje, ale to jest to, co zrobiłem w moich aplikacjach.

<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

Trochę za późno, ale oto rozwiązanie, które zadziałało dla mnie.

użyłem konwertera, aby nowy obraz dla każdego 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> 
+0

To działało świetnie w jednym określonym scenariuszu, dzięki. –

Powiązane problemy