如何在App.xaml中使用图标定义MenuItems作为模板

时间:2012-06-15 15:15:14

标签: wpf xaml

在我的应用中,我有很多上下文菜单。它们中的大多数都包含许多标准条目,例如剪切,复制和粘贴命令的菜单项。每个菜单都有一个附加图标。

如何为应用程序范围内可用的每种类型的MenuItem定义样式?下面的xaml主要是我正在寻找的,但是图像的声明是无效的(如果危险的是同时在多个位置使用样式的实例,则不会显示图像)。 / p>

<Style x:Key="CutMenuItem_Style" TargetType="{x:Type MenuItem}" >
     <Setter Property="Command" Value="Cut"/>
     <Setter Property="Header" Value="Cut"/>
     <Setter Property="Icon" >
          <Setter.Value>
              <Image Source="/image/cut_16_16.png" Stretch="None" />
            </Setter.Value>
     </Setter>                                            
</Style>

你是怎么做到的?你为每个菜单类型声明一个ControlTemplate吗?

请注意:我理解为什么上面的xaml无法按预期工作。我对另一种可靠的方法感兴趣,就像我上面的代码一样。

2 个答案:

答案 0 :(得分:2)

我不确定这是否会起作用(没有测试过),但我很想知道你可能有这样的事情:

class MyMenuItem
{
    public ICommand Command { get; set; }
    public string Header { get; set; }
    public ImageSource ImageSource { get; set; }
}

var cutMenuItem = new MyMenuItem()
{
    Command = ...,
    Header = "Cut",
    ImageSource = ...
};

然后使用DataTemplates:

<DataTemplate DataType="{x:Type local:MyMenuItem}">
    <MenuItem Command="{Binding Command}" Header="{Binding Header}" 
              Icon="{Binding ImageSource}" />
    </MenuItem>
</DataTemplate>

然后是你的菜单:

<Menu ItemsSource="{Binding ListOfMyMenuItems}" />

答案 1 :(得分:1)

可能使用IValueConverterRoutedCommands转换为Images。然后可以在全局样式中使用IValueConverter

XAML如下所示:

<Style x:Key="MenuItemBase_Style" TargetType="{x:Type MenuItem}">
    <Setter Property="Icon" Value="{Binding Command,Converter={StaticResource CommandImage_ValueConverter},RelativeSource={RelativeSource Mode=Self}}"/>
</Style>

<Style x:Key="CutMenuItem_Style" BasedOn="{StaticResource MenuItemBase_Style}"  TargetType="{x:Type MenuItem}" >
    <Setter Property="Command" Value="Cut"/>
</Style>
<Style x:Key="CopyMenuItem_Style" BasedOn="{StaticResource MenuItemBase_Style}"  TargetType="{x:Type MenuItem}" >
    <Setter Property="Command" Value="Copy"/>
</Style>
<Style x:Key="AnotherMenuItem_Style" ... />

IValueConverter 很简单,但也可以扩展到其他方面。我已经写好了,你可以提供Style作为参数。如果您想操纵返回的Image

,这很有用
public class CommandImageValueConverter : IValueConverter{

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
        if (value == null) return null;
        var cmd = value as RoutedCommand;
        if (null != cmd) {                
            var uri = new Uri("/YourComponent;component/Image/" + cmd.Name + "_16_16.png", UriKind.Relative);                
            return new Image() { Stretch = Stretch.None ,Source=Load(uri),Style=parameter as Style};                
        }            
        throw new NotImplementedException("Conversion from " + value.GetType().Name + " is currently not supported");
    }

    public static ImageSource Load(Uri uri) {
        BitmapImage bi = new BitmapImage();
        bi.BeginInit();
        bi.UriSource = uri;
        bi.EndInit();
        return bi;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
        throw new NotImplementedException();
    }
}

IValueConverter也必须声明一次:

<yourNamespace:CommandImageValueConverter x:Key="CommandImage_ValueConverter"/>

希望这有助于其他人。