可以显示来自资源 URI 的 .png 和基于矢量的图像的菜单项 属性
MenuItem that can Show Both .png and Vector Based Images from a Resource URI Property
我在资源字典中有以下 MenuItem
样式
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Controls="clr-namespace:GambitFramework.Modules.MainMenu.Controls"
xmlns:Converters="clr-namespace:GambitFramework.Core.Converters"
xmlns:Behaviors="clr-namespace:GambitFramework.Modules.MainMenu.Behaviors">
<Converters:NullableValueConverter x:Key="NullableValueConverter"/>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
<Image x:Key="MenuItemIcon"
x:Shared="false"
Source="{Binding IconSource, Converter={StaticResource NullableValueConverter}}"/>
<Style x:Key="MenuItem" TargetType="{x:Type Controls:MenuItemEx}">
<Setter Property="Visibility" Value="{Binding IsVisible, Converter={StaticResource BooleanToVisibilityConverter}}"/>
<Setter Property="InputGestureText" Value="{Binding InputGestureText}"/>
<Setter Property="Icon" Value="{StaticResource MenuItemIcon}"/>
<Setter Property="IsCheckable" Value="{Binding IsChecked, Mode=OneWay}"/>
<Setter Property="IsChecked" Value="{Binding IsChecked, Mode=OneWay}"/>
<Setter Property="Command" Value="{Binding Command}"/>
<Setter Property="Behaviors:MenuBehavior.UpdateCommandUiItems" Value="True"/>
</Style>
<HierarchicalDataTemplate x:Key="MenuTemplate" ItemsSource="{Binding Children}">
<ContentPresenter Content="{Binding Path=Text}" RecognizesAccessKey="True"/>
</HierarchicalDataTemplate>
</ResourceDictionary>
这适用于 .png 资源类型,我的 IconSource
属性 可能类似于
public override Uri IconSource
{
get { return new Uri("pack://application:,,,/GambitFramework;component/Resources/Icons/Undo.png"); }
}
现在,我有一个可供我使用的大型矢量图形图标库,我想添加指定 .png 的 URI 或资源字典中指定的某些矢量图形资源的功能,例如
<ResourceDictionary x:Class="resources_icons_xaml"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<Canvas x:Key="appbar_acorn" Width="48" Height="48" Clip="F1 M 0,0L 48,0L 48,48L 0,48L 0,0">
<Path Width="22.3248" Height="25.8518" Canvas.Left="13.6757" Canvas.Top="11.4012" Stretch="Fill" Fill="{DynamicResource BlackBrush}" Data="F1 M 16.6309,18.6563C 17.1309,8.15625 29.8809,14.1563 29.8809,14.1563C 30.8809,11.1563 34.1308,11.4063 34.1308,11.4063C 33.5,12 34.6309,13.1563 34.6309,13.1563C 32.1309,13.1562 31.1309,14.9062 31.1309,14.9062C 41.1309,23.9062 32.6309,27.9063 32.6309,27.9062C 24.6309,24.9063 21.1309,22.1562 16.6309,18.6563 Z M 16.6309,19.9063C 21.6309,24.1563 25.1309,26.1562 31.6309,28.6562C 31.6309,28.6562 26.3809,39.1562 18.3809,36.1563C 18.3809,36.1563 18,38 16.3809,36.9063C 15,36 16.3809,34.9063 16.3809,34.9063C 16.3809,34.9063 10.1309,30.9062 16.6309,19.9063 Z "/>
</Canvas>
...
</ResourceDictionary>
如何修改我的 MenuItem
样式,以便我可以将 URI 用于 .png 和 URI 用于矢量图形?
我主要感兴趣的是如何在 XAML 中以适当的方式区分和显示资源,我从未见过这样做,我对如何去做感到困惑。
感谢您的宝贵时间。
在以前的系统版本中,我只有矢量图形支持,XAML MenuItem
样式是
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Caliburn="http://www.caliburnproject.org"
xmlns:Converters="clr-namespace:GambitFramework.Core.Converters"
xmlns:Controls="clr-namespace:GambitFramework.Modules.MainMenu.Controls">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary>
<Converters:StringToResourceConverter x:Key="StringToResourceDictionary"/>
</ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
<Rectangle x:Key="MenuItemIcon" x:Shared="False"
Visibility="{Binding IconVisibility}"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
Width="16" Height="16">
<Rectangle.Fill>
<VisualBrush Stretch="Uniform" Visual="{Binding IconSource}"/>
</Rectangle.Fill>
</Rectangle>
<Style x:Key="MenuItem" TargetType="{x:Type Controls:MenuItemEx}">
<Setter Property="Icon" Value="{StaticResource MenuItemIcon}"/>
<Setter Property="InputGestureText" Value="{Binding InputGestureText}"/>
<Setter Property="Caliburn:Action.Target" Value="{Binding}"/>
<Setter Property="Caliburn:Message.Attach" Value="{Binding ActionText}"/>
</Style>
<Style x:Key="CheckableMenuItem"
TargetType="{x:Type Controls:MenuItemEx}"
BasedOn="{StaticResource MenuItem}">
<Setter Property="IsCheckable" Value="True"/>
<Setter Property="IsChecked" Value="{Binding IsChecked}"/>
</Style>
<HierarchicalDataTemplate x:Key="MenuTemplate"
ItemsSource="{Binding Children}">
<ContentPresenter Content="{Binding Path=Text}" RecognizesAccessKey="True"/>
</HierarchicalDataTemplate>
</ResourceDictionary>
绑定源所在的位置
public Canvas IconSource
{
get { return iconSource; }
set
{
iconSource = value;
IconVisibility = iconSource == null ?
Visibility.Collapsed :
Visibility.Visible;
NotifyOfPropertyChange(() => IconSource);
}
}
首先,您需要更好地建模 类。矢量图形没有"URI"。
从这里开始:
public abstract class IconPresentation{}
public sealed class ImageIconPresentation : IconPresentation
{
private readonly string _url;
public Uri IconSource
{
get { return new Uri(_url); }
}
public ImageIconPresentation(string url){
_url = url;
}
}
public sealed class ResourceIconPresentation : IconPresentation
{
public string Name
{
get;
private set;
}
public ResourceIconPresentation(string name){
Name = name;
}
}
完成后,您必须修改 Icon
的模板:
<Setter Property="Icon">
<Setter.Value>
<ContentControl Content="{Binding Icon}"/>
</Setter.Value>
</Setter>
现在您只需要为每个图标显示声明 DataTemplate
组。
<DataTemplate DataType="{x:Type ImageIconPresentation}">
<Image Source="{Binding IconSource}" />
</DataTemplate>
<DataTemplate DataType="{x:Type ResourceIconPresentation}">
<Rectangle ..>
<Rectangle.Fill>
<VisualBrush Stretch="Uniform"
Visual="{ext:ResourceKeyBinding Path=Name}"/>
</Rectangle.Fill>
</Rectangle>
</DataTemplate>
就是这样!
您的视图模型会 属性 这样:
public IconPresentation Icon { get; private set; }
ps,我用的是"StaticResource key binding",默认没有。可以从这里找到:Is it possible to dynamically create a ResourceKey for a StaticResource? (eg using a Binding)
我在资源字典中有以下 MenuItem
样式
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Controls="clr-namespace:GambitFramework.Modules.MainMenu.Controls"
xmlns:Converters="clr-namespace:GambitFramework.Core.Converters"
xmlns:Behaviors="clr-namespace:GambitFramework.Modules.MainMenu.Behaviors">
<Converters:NullableValueConverter x:Key="NullableValueConverter"/>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
<Image x:Key="MenuItemIcon"
x:Shared="false"
Source="{Binding IconSource, Converter={StaticResource NullableValueConverter}}"/>
<Style x:Key="MenuItem" TargetType="{x:Type Controls:MenuItemEx}">
<Setter Property="Visibility" Value="{Binding IsVisible, Converter={StaticResource BooleanToVisibilityConverter}}"/>
<Setter Property="InputGestureText" Value="{Binding InputGestureText}"/>
<Setter Property="Icon" Value="{StaticResource MenuItemIcon}"/>
<Setter Property="IsCheckable" Value="{Binding IsChecked, Mode=OneWay}"/>
<Setter Property="IsChecked" Value="{Binding IsChecked, Mode=OneWay}"/>
<Setter Property="Command" Value="{Binding Command}"/>
<Setter Property="Behaviors:MenuBehavior.UpdateCommandUiItems" Value="True"/>
</Style>
<HierarchicalDataTemplate x:Key="MenuTemplate" ItemsSource="{Binding Children}">
<ContentPresenter Content="{Binding Path=Text}" RecognizesAccessKey="True"/>
</HierarchicalDataTemplate>
</ResourceDictionary>
这适用于 .png 资源类型,我的 IconSource
属性 可能类似于
public override Uri IconSource
{
get { return new Uri("pack://application:,,,/GambitFramework;component/Resources/Icons/Undo.png"); }
}
现在,我有一个可供我使用的大型矢量图形图标库,我想添加指定 .png 的 URI 或资源字典中指定的某些矢量图形资源的功能,例如
<ResourceDictionary x:Class="resources_icons_xaml"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<Canvas x:Key="appbar_acorn" Width="48" Height="48" Clip="F1 M 0,0L 48,0L 48,48L 0,48L 0,0">
<Path Width="22.3248" Height="25.8518" Canvas.Left="13.6757" Canvas.Top="11.4012" Stretch="Fill" Fill="{DynamicResource BlackBrush}" Data="F1 M 16.6309,18.6563C 17.1309,8.15625 29.8809,14.1563 29.8809,14.1563C 30.8809,11.1563 34.1308,11.4063 34.1308,11.4063C 33.5,12 34.6309,13.1563 34.6309,13.1563C 32.1309,13.1562 31.1309,14.9062 31.1309,14.9062C 41.1309,23.9062 32.6309,27.9063 32.6309,27.9062C 24.6309,24.9063 21.1309,22.1562 16.6309,18.6563 Z M 16.6309,19.9063C 21.6309,24.1563 25.1309,26.1562 31.6309,28.6562C 31.6309,28.6562 26.3809,39.1562 18.3809,36.1563C 18.3809,36.1563 18,38 16.3809,36.9063C 15,36 16.3809,34.9063 16.3809,34.9063C 16.3809,34.9063 10.1309,30.9062 16.6309,19.9063 Z "/>
</Canvas>
...
</ResourceDictionary>
如何修改我的 MenuItem
样式,以便我可以将 URI 用于 .png 和 URI 用于矢量图形?
我主要感兴趣的是如何在 XAML 中以适当的方式区分和显示资源,我从未见过这样做,我对如何去做感到困惑。
感谢您的宝贵时间。
在以前的系统版本中,我只有矢量图形支持,XAML MenuItem
样式是
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Caliburn="http://www.caliburnproject.org"
xmlns:Converters="clr-namespace:GambitFramework.Core.Converters"
xmlns:Controls="clr-namespace:GambitFramework.Modules.MainMenu.Controls">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary>
<Converters:StringToResourceConverter x:Key="StringToResourceDictionary"/>
</ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
<Rectangle x:Key="MenuItemIcon" x:Shared="False"
Visibility="{Binding IconVisibility}"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
Width="16" Height="16">
<Rectangle.Fill>
<VisualBrush Stretch="Uniform" Visual="{Binding IconSource}"/>
</Rectangle.Fill>
</Rectangle>
<Style x:Key="MenuItem" TargetType="{x:Type Controls:MenuItemEx}">
<Setter Property="Icon" Value="{StaticResource MenuItemIcon}"/>
<Setter Property="InputGestureText" Value="{Binding InputGestureText}"/>
<Setter Property="Caliburn:Action.Target" Value="{Binding}"/>
<Setter Property="Caliburn:Message.Attach" Value="{Binding ActionText}"/>
</Style>
<Style x:Key="CheckableMenuItem"
TargetType="{x:Type Controls:MenuItemEx}"
BasedOn="{StaticResource MenuItem}">
<Setter Property="IsCheckable" Value="True"/>
<Setter Property="IsChecked" Value="{Binding IsChecked}"/>
</Style>
<HierarchicalDataTemplate x:Key="MenuTemplate"
ItemsSource="{Binding Children}">
<ContentPresenter Content="{Binding Path=Text}" RecognizesAccessKey="True"/>
</HierarchicalDataTemplate>
</ResourceDictionary>
绑定源所在的位置
public Canvas IconSource
{
get { return iconSource; }
set
{
iconSource = value;
IconVisibility = iconSource == null ?
Visibility.Collapsed :
Visibility.Visible;
NotifyOfPropertyChange(() => IconSource);
}
}
首先,您需要更好地建模 类。矢量图形没有"URI"。
从这里开始:
public abstract class IconPresentation{}
public sealed class ImageIconPresentation : IconPresentation
{
private readonly string _url;
public Uri IconSource
{
get { return new Uri(_url); }
}
public ImageIconPresentation(string url){
_url = url;
}
}
public sealed class ResourceIconPresentation : IconPresentation
{
public string Name
{
get;
private set;
}
public ResourceIconPresentation(string name){
Name = name;
}
}
完成后,您必须修改 Icon
的模板:
<Setter Property="Icon">
<Setter.Value>
<ContentControl Content="{Binding Icon}"/>
</Setter.Value>
</Setter>
现在您只需要为每个图标显示声明 DataTemplate
组。
<DataTemplate DataType="{x:Type ImageIconPresentation}">
<Image Source="{Binding IconSource}" />
</DataTemplate>
<DataTemplate DataType="{x:Type ResourceIconPresentation}">
<Rectangle ..>
<Rectangle.Fill>
<VisualBrush Stretch="Uniform"
Visual="{ext:ResourceKeyBinding Path=Name}"/>
</Rectangle.Fill>
</Rectangle>
</DataTemplate>
就是这样!
您的视图模型会 属性 这样:
public IconPresentation Icon { get; private set; }
ps,我用的是"StaticResource key binding",默认没有。可以从这里找到:Is it possible to dynamically create a ResourceKey for a StaticResource? (eg using a Binding)