c# - WPF SVG 图标资源
问题描述
有没有办法将 SVG 图标创建为可以在多个位置(例如 a Button
、 aLabel
和a 中的Icon
a )轻松工作的资源FileMenuItem
?
例子
应用程序.xaml
...
<Application.Resources>
<Icon x:Key="MyIcon" Data="...PathData..." />
</Application.Resources>
...
主窗口.xaml
...
<MenuItem Header="Do Stuff" Icon="{StaticResource MyIcon}" />
...
<StackPanel>
<Label Content="{StaticResource MyIcon}" />
<Button Content="{StaticResource MyIcon}" />
</StackPanel>
...
我试过的
我尝试将图标定义为Geometry
和 aPath
但两者都有并发症。在Geometry
你必须指定一个Path
元素并设置它的Data
属性的情况下,这会给代码添加一堆杂乱无章的东西。在某些情况下使用 aPath
可以解决这个问题,但对于FileMenuItem
我发现我必须将路径包装在 aCanvas
或 a中Border
,再次为代码添加一些杂乱无章的东西。
解决方案
在做了一些研究和实验之后,我最终创建了一个UserControl
将 a 包装在 aPath
中的 aContentControl
然后提供一对DependencyProperty
s 以便可以设置图标Data
和Stretch
属性。
编码
SvgIcon.xaml.cs
public partial class SvgIcon : UserControl
{
public SvgIcon()
{
InitializeComponent();
}
public Geometry Data
{
get { return (Geometry) GetValue(DataProperty); }
set { SetValue(DataProperty, value); }
}
public Stretch Stretch
{
get { return (Stretch) GetValue(StretchProperty); }
set { SetValue(StretchProperty, value); }
}
public static readonly DependencyProperty DataProperty = DependencyProperty.Register("Data", typeof(Geometry), typeof(SvgIcon));
public static readonly DependencyProperty StretchProperty = DependencyProperty.Register("Stretch", typeof(Stretch), typeof(SvgIcon));
}
SVG图标.cs
<UserControl x:Name="Root" ...etc...>
<ContentControl>
<Path Data="{Binding Data, ElementName=Root}" Fill="{Binding Foreground, ElementName=Root}" Stretch="{Binding Stretch, ElementName=Root}" />
</ContentControl>
</UserControl>
示例用法
应用程序.xaml
...
<Application.Resources>
<myns:SvgIcon x:Key="MyIcon" Data="...PathData..." Foreground="Black" />
</Application.Resources>
...
主窗口.xaml
...
<MenuItem Header="Do Stuff" Icon="{StaticResource MyIcon}" />
...
<StackPanel>
<Label Content="{StaticResource MyIcon}" />
<Button Content="{StaticResource MyIcon}" />
</StackPanel>
...
使用这种方法有几个好处UserControl
,主要是可以轻松地将样式应用于图标。然而,一个小痛点是将样式应用于资源文件之外的图标,例如更改文件菜单中的颜色。以下是如何实现这一目标的示例。
应用程序.xaml
...
<Application.Resources>
<myns:SvgIcon x:Key="MyIcon" Data="...PathData..." />
...
/*Default Icon Style*/
<Style TargetType="myns:SvgIcon">
<Setter Property="Foreground" Value="Black" />
</Style>
/*Style icons used as content*/
<Style TargetType="Control" x:Key="BlueIcon">
<Style.Resources>
<Style TargetType="myns:SvgIcon" BasedOn="{StaticResource {x:Type myns:SvgIcon}}">
<Setter Property="Foreground" Value="Blue" />
</Style>
</Style.Resources>
</Style>
...
</Application.Resources>
...
主窗口.xaml
...
<MenuItem Header="Do Stuff" Icon="{StaticResource MyIcon}" Style="{StaticResource BlueIcon}" />
...
<StackPanel>
<Label Content="{StaticResource MyIcon}" Style="{StaticResource BlueIcon}" />
<Button Content="{StaticResource MyIcon}" Style="{StaticResource BlueIcon}" />
</StackPanel>
...
可能还有其他聪明的解决方案,但这对于我想要实现的目标非常有效。
推荐阅读
- javascript - SyntaxError:无法在模块外使用 import 语句,如何使用 react-native-svg 为 Web 运行测试单元?
- groovy - 为什么我在 Jenkins 管道 groovy 中看到这种行为
- mongodb - MongoDB 聚合用例
- amazon-emr - 当我使用 zeppelin 时,Amazon EMR 集群可能停止响应
- php - 为什么我的随机函数总是返回相同的数字?
- r - 安装 rstan/brms 后的浮点异常
- css - 在轮播中设置相同高度的图像
- javascript - 有没有查找平均年龄的功能?
- javascript - How do I query a Key-Value object in Java
- python-3.x - Python aiohttp Azure Function ClientConnector 错误(在本地工作)