2011-06-24 9 views
5

Tôi cố gắng để thiết lập các biểu tượng của mục trình đơn của tôi như thế này -Không thể đặt biểu tượng cho các mục menu sử dụng 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> 

nhưng biểu tượng cho chỉ cuối cùng mục menu được hiển thị và không cho hai đầu tiên.

enter image description here

Ứng dụng mẫu - http://weblogs.asp.net/blogs/akjoshi/Samples/WPFMenuItemBugSample.zip

bất cứ ai có thể cho biết lý do cho hành vi này và giải pháp khả thi/cách giải quyết.

Trả lời

8

Đó là bởi vì bạn đã sử dụng một Image tài nguyên của bạn. Một Image là một điều khiển và - giống như bất kỳ điều khiển khác - chỉ có thể có một phụ huynh. Theo mặc định, WPF sẽ cố gắng chia sẻ tài nguyên trên tất cả người tiêu dùng. Như vậy, cuối cùng MenuItem "chiến thắng" quyền giam giữ cho Image và khác MenuItem 's thậm chí không được phép thăm viếng cuối tuần.

Để khắc phục điều này, bạn có thể hoặc thiết lập các Image là không chia sẻ:

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

Hoặc tốt hơn nữa, biểu hiện tài nguyên hình ảnh của bạn như ImageSource lớp con thích hợp và chia sẻ rằng thay vì:

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

Cảm ơn Kent, nhưng tiếc là cả hai giải pháp không hoạt động. Không có tác động đầu tiên và thứ hai tạo ra ngoại lệ sau đây: - Không thể thêm nội dung kiểu 'System.Windows.Controls.Image' vào đối tượng kiểu 'System.Object'. Lỗi tại đối tượng 'System.Windows.Controls.Image' trong tệp đánh dấu 'Sample; component/window1.xaml' Line 27 Position 34. – akjoshi

+0

Trong trường hợp nó giúp, tôi đã tải lên ứng dụng mẫu sao chép vấn đề này trong câu hỏi; – akjoshi

+2

@akjoshi: cảm ơn vì repro. Chuyển dự án của bạn sang WPF 4 cho phép đề xuất đầu tiên của tôi hoạt động, vì vậy phải có một lỗi trong 3.5. Đối với đề nghị thứ hai của tôi, điều đó sẽ không hoạt động vì WPF đang cố gắng sử dụng cùng một hình ảnh trên tất cả các MenuItems, theo cách tôi mô tả trong câu trả lời của tôi. Nếu có thuộc tính 'IconTemplate', bạn sẽ sử dụng nó. Thật không may, 'MenuItem' không đủ chi tiết để có, vì vậy tôi chỉ có thể đề nghị ghi đè' Mẫu' thay thế. Bực bội để nói rằng ít nhất. –

0

nó sẽ làm việc để chỉ cần thêm một đặc tính biểu tượng cho mỗi mục trình đơn trực tiếp, mà không sử dụng một phong cách? Có lẽ tôi đang thiếu một cái gì đó, nhưng đây là những gì tôi đã làm trong các ứng dụng của tôi.

<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

Một chút trễ, nhưng đây là giải pháp phù hợp với tôi.

tôi đã sử dụng một bộ chuyển đổi để thực hiện một hình ảnh mới cho mỗi 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

Điều này làm việc tuyệt vời trong một kịch bản cụ thể, cảm ơn. –