После некоторых исследований и экспериментов я закончил тем, что создал UserControl
, который оборачивает Path
в ContentControl
, а затем предоставил пару 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));
}
SvgIcon.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>
Пример использования
App.xaml
...
<Application.Resources>
<myns:SvgIcon x:Key="MyIcon" Data="...PathData..." Foreground="Black" />
</Application.Resources>
...
MainWindow.xaml
...
<MenuItem Header="Do Stuff" Icon="{StaticResource MyIcon}" />
...
<StackPanel>
<Label Content="{StaticResource MyIcon}" />
<Button Content="{StaticResource MyIcon}" />
</StackPanel>
...
Использование подхода UserControl
имеет несколько преимуществ, в основном это то, что стили могут быть легко применены к иконке. Тем не менее, одной из незначительных проблем является применение стилей к значку за пределами файла ресурсов, например, изменение цвета в меню файла. Ниже приведен пример того, как этого можно достичь.
App.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>
...
MainWindow.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>
...
Могут быть и другие умные решения, но это очень хорошо сработало для того, чего я стремился достичь.