WPF SVG Icon Resources - PullRequest
       2

WPF SVG Icon Resources

0 голосов
/ 04 апреля 2019

Есть ли способ создания значков SVG в качестве ресурсов, которые будут легко работать в нескольких местах, таких как Button, Label и как Icon в FileMenuItem?

Пример

App.xaml

... 
<Application.Resources>
    <Icon x:Key="MyIcon" Data="...PathData..." />
</Application.Resources>
...

MainWindow.xaml

...
<MenuItem Header="Do Stuff" Icon="{StaticResource MyIcon}" />
...
<StackPanel>
    <Label Content="{StaticResource MyIcon}" />
    <Button Content="{StaticResource MyIcon}" />
</StackPanel>
...

Что я пробовал

Я пытался определить значки как Geometry и Path, но у обоих есть сложности.В случае Geometry вы должны указать элемент Path и установить его свойство Data, которое добавляет в код кучу лжи.Использование Path в некоторых случаях позволяет обойти это, но для FileMenuItem я обнаружил, что мне нужно обернуть путь в Canvas или Border, снова добавив немного кода в код.

1 Ответ

0 голосов
/ 04 апреля 2019

После некоторых исследований и экспериментов я закончил тем, что создал 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>
...

Могут быть и другие умные решения, но это очень хорошо сработало для того, чего я стремился достичь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...