2

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

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

<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 不能按预期工作。我对一种替代且可靠的方法感兴趣,可以按照我对上述代码的预期进行操作。

4

2 回答 2

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}" />
于 2012-06-15T15:45:53.890 回答
1

一种可能性是使用IValueConverter转换RoutedCommands为的 a 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很简单,但也可以针对其他事物进行扩展。我已经这样写了,您可以提供 aStyle作为参数。如果您想操作返回的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"/>

希望这对其他人有帮助。

于 2012-06-15T19:20:17.590 回答