在我的应用中,我有很多上下文菜单。它们中的大多数都包含许多标准条目,例如剪切,复制和粘贴命令的菜单项。每个菜单都有一个附加图标。
如何为应用程序范围内可用的每种类型的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无法按预期工作。我对另一种可靠的方法感兴趣,就像我上面的代码一样。
答案 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)
可能使用IValueConverter
将RoutedCommands
转换为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"/>
希望这有助于其他人。