Windows 8中WPF菜单项图标行为的解决方法

时间:2013-02-06 11:19:33

标签: wpf windows-8

我的WPF应用程序中有一个菜单,它使用PNG图像作为图标。这些图像作为资源存储在单独的DLL中。在旧版本的Windows中,图标(48x48像素)显示正确,缩小到容器的大小。

在Windows 8中,图标表现不同。

以下是我的代码示例:

<MenuItem Header="Promotions" x:Name="mnuPromotions" Style="{StaticResource styMenuItem}">
    <MenuItem.Icon>
        <Image Source="{StaticResource icnPromotion_48}" Style="{StaticResource styMenuIcon}" />
    </MenuItem.Icon>
</MenuItem>
<MenuItem Header="Catalogues" x:Name="mnuCatalogues" Style="{StaticResource styMenuItem}">
    <MenuItem.Icon>
        <Image Source="{StaticResource icnCatalogue_48}" Style="{StaticResource styMenuIcon}" />
    </MenuItem.Icon>
</MenuItem>
  <MenuItem Header="Customer Price Lists" x:Name="mnuCustomerPriceLists">
    <MenuItem.Icon>
        <Image Source="{StaticResource icnCashCustomer_48}" Style="{StaticResource styMenuIcon}" />
    </MenuItem.Icon>
</MenuItem>

这是菜单项的样式

<Style x:Key="styMenuItem" TargetType="MenuItem">
  <Setter Property="Foreground" Value="#FF000000" />
  <Setter Property="FontSize" Value="22" />
  <Setter Property="Margin" Value="2" />
  <Setter Property="Background">
    <Setter.Value>
      <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
        <GradientStop Offset="0" Color="#AA9D9D9D" />
        <GradientStop Offset="1" Color="#AACFCDBE" />
      </LinearGradientBrush>
    </Setter.Value>
  </Setter>
</Style>

这是Icon的风格

<Style x:Key="styMenuIcon" TargetType="Image">
  <Setter Property="Width" Value="20" />
  <Setter Property="Height" Value="20" />
  <Setter Property="VerticalAlignment" Value="Center" />
  <Setter Property="HorizontalAlignment" Value="Center" />
  <Setter Property="Margin" Value="2" />
</Style>

这是旧版Windows中菜单的样子: Menu in Windows XP to Windows 7

这就是Windows 8中的菜单 Menu in Windows 8

如果仔细观察,图标会在Win8中居中并裁剪,而它们适合旧版Windows中的容器。

有没有人知道为什么这种行为会发生变化?如果这种行为改变有一个简单的解决方法,那么菜单与从XP到8的所有Windows版本完全兼容?

2 个答案:

答案 0 :(得分:2)

看起来这种行为是一个已知的错误,(像往常一样)Microsof不想修复:

http://connect.microsoft.com/VisualStudio/feedback/details/767328/menuitem-icon-wont-stretch-when-changing-size-in-windows-8

发布了两个解决方法,简单的是将图像高度调整为每个XAML的菜单项高度:

<MenuItem x:Name="ctxMenuName" Header="Open Existing">
  <MenuItem.Icon>
     <Image Source="/MyApp;component/Images/folder_with_file.png"
                 Height="{Binding Path=ActualHeight, ElementName=ctxMenuName}"
                 Width="{Binding Path=ActualHeight, ElementName=ctxMenuName}" />
  </MenuItem.Icon>
</MenuItem> 

答案 1 :(得分:1)

尝试升级现有的WPF应用程序以支持Windows 10.这是一种从MenuItem继承的解决方法。这将适用于其他内容以及图像。

using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace MenuItemDemo
{
    public class MenuItemEx : MenuItem
    {
        public MenuItemEx()
        {
            base.Loaded += FrameworkElement_OnLoaded;
        }

        private void FrameworkElement_OnLoaded(object sender, RoutedEventArgs e)
        {
            var child = Icon as FrameworkElement;
            if (child == null)
                return;

            var parent = VisualTreeHelper.GetParent(child) as ContentPresenter;
            if (parent == null)
                return;

            parent.Width = child.Width;
            parent.Height = child.Height;
        }
    }
}

然后在xaml中使用它引用xmlns:menuitem="clr-namespace:MenuItemDemo",然后将<MenuItem>更改为<menuitem:MenuItemEx>

使用此

的示例窗口
<Window x:Class="MenuItemDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:menuitem="clr-namespace:MenuItemDemo"
        Title="MainWindow" Height="350" Width="525">    
        <DockPanel>
            <Menu DockPanel.Dock="Top">
                <menuitem:MenuItemEx>
                    <MenuItem.Icon>
                        <Label>Text asdfasdf</Label>
                    </MenuItem.Icon>
                </menuitem:MenuItemEx>  
            </Menu>
            <Grid></Grid>
        </DockPanel>     
</Window>