我试图移动一些XAML定义MenuItem到风格。设置样式附WPPM MenuItem图标
我已经得到了以下工作XAML:
<Menu x:Name="menu" Height="19" Margin="10,10,10.333,0" VerticalAlignment="Top">
<MenuItem Header="_Open">
<MenuItem.Icon>
<Viewbox>
<ContentControl Content="{DynamicResource appbar.folder.open}" RenderTransformOrigin="0.5,0.5">
<ContentControl.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="2" ScaleY="2"/>
</TransformGroup>
</ContentControl.RenderTransform>
</ContentControl>
</Viewbox>
</MenuItem.Icon>
</MenuItem>
</Menu>
在资源看起来是这样的:
<?xml version="1.0" encoding="utf-8"?>
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Key="appbar.folder.open" Width="76" Height="76" Clip="F1 M 0,0L 76,0L 76,76L 0,76L 0,0">
<Path Width="44" Height="26" Canvas.Left="19" Canvas.Top="24" Stretch="Fill" Fill="#FF000000" Data="F1 M 19,50L 28,34L 63,34L 54,50L 19,50 Z M 19,28.0001L 35,28C 36,25 37.4999,24.0001 37.4999,24.0001L 48.75,24C 49.3023,24 50,24.6977 50,25.25L 50,28L 53.9999,28.0001L 53.9999,32L 27,32L 19,46.4L 19,28.0001 Z "/>
</Canvas>
</ResourceDictionary>
一点题外话,我也不知道该如何摆脱明确的缩放。这似乎是一个小问题,但我将不胜感激,如果这也可以解决。
总之,要尽可能这个有点太传神的定义移动到风格,我创建的代码为Visual
namespace extensions
{
public class AttachedProperties
{
public static readonly DependencyProperty VisualIconProperty =
DependencyProperty.RegisterAttached("VisualIcon",
typeof(System.Windows.Media.Visual), typeof(AttachedProperties),
new PropertyMetadata(default(System.Windows.Media.Visual)));
public static void SetVisualIcon(UIElement element, System.Windows.Media.Visual value)
{
element.SetValue(VisualIconProperty, value);
}
public static System.Windows.Media.Visual GetVisualIcon(UIElement element)
{
return (System.Windows.Media.Visual)element.GetValue(VisualIconProperty);
}
}
}
类型的附加属性重新定义菜单项
<MenuItem Header="_Open"
Style="{StaticResource MenuItemStyle}"
extensions:AttachedProperties.VisualIcon="{DynamicResource appbar.folder.open}" />
并尝试创建一个读取VisualIcon属性以设置图标内容的样式
<Style x:Key="MenuItemStyle" TargetType="MenuItem">
<Setter Property="MenuItem.Icon">
<Setter.Value>
<Viewbox>
<ContentControl RenderTransformOrigin="0.5,0.5">
<ContentControl.Content>
<!-- this would work but doesn't reference the VisualIcon property.. <DynamicResource ResourceKey="appbar.folder.open"/> -->
<!-- these do not -->
<Binding Path="(extensions:AttachedProperties.VisualIcon)" RelativeSource="{RelativeSource FindAncestor, AncestorType=MenuItem}"/>-->
<!--<Binding Path="(extensions:AttachedProperties.VisualIcon)" RelativeSource="{RelativeSource TemplatedParent}"/>-->
<!--<Binding Path="(extensions:AttachedProperties.VisualIcon)" RelativeSource="{RelativeSource Self}"/>-->
</ContentControl.Content>
<ContentControl.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="2" ScaleY="2"/>
</TransformGroup>
</ContentControl.RenderTransform>
</ContentControl>
</Viewbox>
</Setter.Value>
</Setter>
</Style>
但失败。引用具有DynamicResource和静态密钥的资源,但我无法使用附加属性进行任何绑定。
由于我是WPF初学者,我不确定这是否是一个好方法。
[EDIT1]
我测试所有提供的解决方案。 Grek40的answer没有为我显示任何图标,无论是在设计视图还是在运行时;也许我做了完全错误的事情。
grx70的第二种方法second answer它对我来说最有希望,因为它在设计视图中以及在运行时可靠地显示图标。 然而,似乎Win7和Win10之间我不明白。我在Win7和Win10上测试了相同的源代码(在外部驱动器上)。对于Win10,它看起来不错,但Win7绘制的图标太大了。
(注:原因是this comment给)
这里的窗口testcode:
<Window.Resources>
<Style x:Key="MenuItemStyle" TargetType="controls:MenuItemEx">
<Setter Property="MenuItem.Icon">
<Setter.Value>
<Viewbox>
<ContentControl RenderTransformOrigin="0.5,0.5">
<ContentControl.Content>
<Binding Path="(extensions:AttachedProperties.VisualIcon)" RelativeSource="{RelativeSource FindAncestor, AncestorType=MenuItem}"/>
</ContentControl.Content>
<ContentControl.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="2" ScaleY="2"/>
</TransformGroup>
</ContentControl.RenderTransform>
</ContentControl>
</Viewbox>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="MenuItemStyle2" TargetType="MenuItem">
<Setter Property="uihelpers:MenuItemHelper.IsEnabled" Value="True" />
<Setter Property="MenuItem.Icon">
<Setter.Value>
<Viewbox>
<ContentControl RenderTransformOrigin="0.5,0.5"
Content="{Binding
Path=(uihelpers:MenuItemHelper.MenuItem).(extensions:AttachedProperties.VisualIcon),
RelativeSource={RelativeSource AncestorType=Viewbox}}">
<ContentControl.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="2" ScaleY="2"/>
</TransformGroup>
</ContentControl.RenderTransform>
</ContentControl>
</Viewbox>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="MenuItemStyle3" TargetType="{x:Type MenuItem}">
<Style.Resources>
<DataTemplate x:Key="MenuItemStyle3dt" DataType="{x:Type Style}">
<Path Style="{Binding}"
Stretch="Uniform"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</DataTemplate>
</Style.Resources>
</Style>
<Style x:Key="appbar.folder.open.style3.local" TargetType="{x:Type Path}">
<Setter Property="Fill" Value="Black" />
<Setter Property="Data" Value="M0,26 L9,10 L44,10 L35,26 Z M0,4 L16,4 C17,1 18.5,0 18.5,0 L29.75,0 C30.3,0 31,0.7 31,1.25 L31,4 L34,4 L34,8 L8,8 L0,22.4 Z" />
</Style>
<extensions:PathStyle x:Key="appbar.folder.open.style3b">
<Setter Property="Path.HorizontalAlignment" Value="Center" />
<Setter Property="Path.VerticalAlignment" Value="Center" />
<Setter Property="Path.Stretch" Value="Uniform" />
<Setter Property="Path.Fill" Value="Black" />
<Setter Property="Path.Data" Value="M0,26 L9,10 L44,10 L35,26 Z M0,4 L16,4 C17,1 18.5,0 18.5,0 L29.75,0 C30.3,0 31,0.7 31,1.25 L31,4 L34,4 L34,8 L8,8 L0,22.4 Z" />
</extensions:PathStyle>
<DataTemplate DataType="{x:Type extensions:PathStyle}">
<Path Style="{Binding}" />
</DataTemplate>
<Canvas x:Key="appbar.folder.open.style4.local" x:Shared="False" Width="76" Height="76" Clip="F1 M 0,0L 76,0L 76,76L 0,76L 0,0">
<Path Width="44" Height="26" Canvas.Left="19" Canvas.Top="24" Stretch="Fill" Fill="#FF000000" Data="F1 M 19,50L 28,34L 63,34L 54,50L 19,50 Z M 19,28.0001L 35,28C 36,25 37.4999,24.0001 37.4999,24.0001L 48.75,24C 49.3023,24 50,24.6977 50,25.25L 50,28L 53.9999,28.0001L 53.9999,32L 27,32L 19,46.4L 19,28.0001 Z "/>
</Canvas>
<Viewbox x:Key="MenuItemStyle4.Icon" x:Shared="False">
<ContentControl Content="{Binding Path=Tag,RelativeSource={RelativeSource AncestorType=MenuItem}}" RenderTransformOrigin="0.5,0.5">
<ContentControl.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="2" ScaleY="2"/>
</TransformGroup>
</ContentControl.RenderTransform>
</ContentControl>
</Viewbox>
<Style x:Key="MenuItemStyle4" TargetType="MenuItem">
<Setter Property="Icon" Value="{StaticResource MenuItemStyle4.Icon}"/>
</Style>
</Window.Resources>
<Grid>
<Menu x:Name="menu" Height="19" Margin="10,10,10.333,0" VerticalAlignment="Top">
<MenuItem Header="_File">
<controls:MenuItemEx Header="_Open"
Style="{StaticResource MenuItemStyle}"
extensions:AttachedProperties.VisualIcon="{DynamicResource appbar.folder.open}" />
<MenuItem Header="_Open"
Style="{StaticResource MenuItemStyle2}"
extensions:AttachedProperties.VisualIcon="{DynamicResource appbar.folder.open}" />
<MenuItem Header="_Open"
Style="{StaticResource MenuItemStyle3}"
Icon="{DynamicResource appbar.folder.open.style3}" />
<MenuItem Header="_Open"
Style="{StaticResource MenuItemStyle3}"
Icon="{DynamicResource appbar.folder.open.style3.local}" />
<MenuItem Header="_Open" Icon="{DynamicResource appbar.folder.open.style3b}" />
<MenuItem Header="_Open"
Style="{StaticResource MenuItemStyle4}"
Tag="{DynamicResource appbar.folder.open}" />
<MenuItem Header="_Open"
Style="{StaticResource MenuItemStyle4}"
Tag="{DynamicResource appbar.folder.open.style4.local}" />
<MenuItem Header="_Save">
<MenuItem.Icon>
<Viewbox>
<ContentControl Content="{DynamicResource appbar.save}" RenderTransformOrigin="0.5,0.5">
<ContentControl.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="2" ScaleY="2"/>
</TransformGroup>
</ContentControl.RenderTransform>
</ContentControl>
</Viewbox>
</MenuItem.Icon>
</MenuItem>
</MenuItem>
</Menu>
<Menu x:Name="menu2" Height="19" Margin="9,32,11.333,0" VerticalAlignment="Top" ItemContainerStyle="{StaticResource MenuItemStyle4}">
<MenuItem Header="_File">
<MenuItem Header="_Open"
Tag="{DynamicResource appbar.folder.open.style4.local}" />
<MenuItem Header="_Open"
Tag="{DynamicResource appbar.folder.open}" />
</MenuItem>
</Menu>
</Grid>
,这里是全球资源:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Key="appbar.folder.open" x:Shared="False" Width="76" Height="76" Clip="F1 M 0,0L 76,0L 76,76L 0,76L 0,0">
<Path Width="44" Height="26" Canvas.Left="19" Canvas.Top="24" Stretch="Fill" Fill="#FF000000" Data="F1 M 19,50L 28,34L 63,34L 54,50L 19,50 Z M 19,28.0001L 35,28C 36,25 37.4999,24.0001 37.4999,24.0001L 48.75,24C 49.3023,24 50,24.6977 50,25.25L 50,28L 53.9999,28.0001L 53.9999,32L 27,32L 19,46.4L 19,28.0001 Z "/>
</Canvas>
<Style x:Key="appbar.folder.open.style3" TargetType="{x:Type Path}">
<Setter Property="Fill" Value="Black" />
<Setter Property="Data" Value="M0,26 L9,10 L44,10 L35,26 Z M0,4 L16,4 C17,1 18.5,0 18.5,0 L29.75,0 C30.3,0 31,0.7 31,1.25 L31,4 L34,4 L34,8 L8,8 L0,22.4 Z" />
</Style>
</ResourceDictionary>
和
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Key="appbar.save" Width="76" Height="76" Clip="F1 M 0,0L 76,0L 76,76L 0,76L 0,0">
<Path Width="34.8333" Height="34.8333" Canvas.Left="20.5833" Canvas.Top="20.5833" Stretch="Fill" Fill="#FF000000" Data="F1 M 20.5833,20.5833L 55.4167,20.5833L 55.4167,55.4167L 45.9167,55.4167L 45.9167,44.3333L 30.0833,44.3333L 30.0833,55.4167L 20.5833,55.4167L 20.5833,20.5833 Z M 33.25,55.4167L 33.25,50.6667L 39.5833,50.6667L 39.5833,55.4167L 33.25,55.4167 Z M 26.9167,23.75L 26.9167,33.25L 49.0833,33.25L 49.0833,23.75L 26.9167,23.75 Z "/>
</Canvas>
</ResourceDictionary>
它们在app中合并。XAML:
<Application.Resources>
<ResourceDictionary >
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="icons/appbar.folder.open.xaml"/>
<ResourceDictionary Source="icons/appbar.save.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
原因的图标偏移是我把他们或多或少的1:1,从github.com/Templarian/WindowsIcons并希望,因为他们在这个格式提供(我也试图将其保存为画笔,首先使用Inkscape,然后使用Expression Design),像这样使用它们是很常见的。
您是否获得在输出窗口任何约束力相关的错误? – Grx70
@ Grx70为三种不同的方法,只有FindAncestor日志:System.Windows.Data错误:4:找不到与参考'RelativeSource FindAncestor,AncestorType ='System.Windows绑定的源。Controls.MenuItem',AncestorLevel ='1''。 BindingExpression:路径=(0);的DataItem = NULL;目标元素是'ContentControl'(Name ='');目标属性是'内容'(类型'对象')。奇怪的是,“自我”方法在设计视图中将“(0)”显示为图标,但在运行时不显示。 –
根据[本QA](https://stackoverflow.com/questions/15725729/wpf-menuitem-icon-dimensions)'MenuItem'高度因使用的主题而异。不幸的是,没有确定“最佳”图标大小的通用方法 - 例如在_Aero_主题(_Windows 7_的默认设置)中没有任何限制(在布局的度量传递过程中始终存在无限可用空间 - 这来自“MenuItem”模板),因此您的结果(图标变得“一样大因为他们想要“)。可能会有一些解决方法让事情变得更不起作用,但这需要一个不同的问题。 – Grx70