我試圖移動一些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