WPF Как правильно использовать файлы SVG в качестве значков в WPF


может ли кто-нибудь описать рекомендуемую пошаговую процедуру для этого?

EDIT:

Шаг1. Преобразование SVG в XAML... это просто

Шаг2. И что теперь?

4 52
wpf

4 ответа:

ваша техника будет зависеть от того, какой объект XAML создает ваш конвертер SVG в XAML. Это производит рисунок? Изображение? Сетка? Холст? Путь? А Геометрия? В каждом случае ваша техника будет отличаться.

в приведенных ниже примерах я предположу, что вы используете свой значок на кнопке, что является наиболее распространенным сценарием, но обратите внимание, что те же методы будут работать для любого ContentControl.

использование чертежа в качестве значок

чтобы использовать рисунок, нарисуйте прямоугольник подходящего размера с помощью кисти для рисования:

<Button>
  <Rectangle Width="100" Height="100">
    <Rectangle.Fill>
      <DrawingBrush>
        <DrawingBrush.Drawing>

          <Drawing ... /> <!-- Converted from SVG -->

        </DrawingBrush.Drawing>
      </DrawingBrush>
    </Rectangle.Fill>
  </Rectangle>
</Button>

использование изображения в качестве значка

изображение можно использовать сразу:

<Button>
  <Image ... />  <!-- Converted from SVG -->
</Button>

использование сетки в качестве значка

сетка может быть использована непосредственно:

<Button>
  <Grid ... />  <!-- Converted from SVG -->
</Button>

или вы можете включить его в поле просмотра, если вам нужно контролировать размер:

<Button>
  <Viewbox ...>
    <Grid ... />  <!-- Converted from SVG -->
  </Viewbox>
</Button>

С помощью Холст как икона

это похоже на использование изображения или сетки, но поскольку холст не имеет фиксированного размера, вам нужно указать высоту и ширину (если они уже не установлены конвертером SVG):

<Button>
  <Canvas Height="100" Width="100">  <!-- Converted from SVG, with additions -->
  </Canvas>
</Button>

использование пути в качестве значка

вы можете использовать путь, но вы должны установить штрих или заполнить явно:

<Button>
  <Path Stroke="Red" Data="..." /> <!-- Converted from SVG, with additions -->
</Button>

или

<Button>
  <Path Fill="Blue" Data="..." /> <!-- Converted from SVG, with additions -->
</Button>

использование геометрии в качестве значок

вы можете использовать путь для рисования геометрии. Если его нужно погладить, установите поглаживание:

<Button>
  <Path Stroke="Red" Width="100" Height="100">
    <Path.Data>
      <Geometry ... /> <!-- Converted from SVG -->
    </Path.Data>
  </Path>
</Button>

или если он должен быть заполнен, установки Fill:

<Button>
  <Path Fill="Blue" Width="100" Height="100">
    <Path.Data>
      <Geometry ... /> <!-- Converted from SVG -->
    </Path.Data>
  </Path>
</Button>

как привязать данные

если вы выполняете преобразование SVG - > XAML в коде и хотите, чтобы полученный XAML отображался с помощью привязки данных, используйте одно из следующих действий:

привязка чертежа:

<Button>
  <Rectangle Width="100" Height="100">
    <Rectangle.Fill>
      <DrawingBrush Drawing="{Binding Drawing, Source={StaticResource ...}}" />
    </Rectangle.Fill>
  </Rectangle>
</Button>

привязка Изображение:

<Button Content="{Binding Image}" />

привязка к сетке:

<Button Content="{Binding Grid}" />

привязка сетки в поле просмотра:

<Button>
  <Viewbox ...>
    <ContentPresenter Content="{Binding Grid}" />
  </Viewbox>
</Button>

привязка холст:

<Button>
  <ContentPresenter Height="100" Width="100" Content="{Binding Canvas}" />
</Button>

привязка пути:

<Button Content="{Binding Path}" />  <!-- Fill or stroke must be set in code unless set by the SVG converter -->

привязка геометрии:

<Button>
  <Path Width="100" Height="100" Data="{Binding Geometry}" />
</Button>

Я нашел лучший способ для меня, чтобы использовать иконки в формате SVG в WPF. Я использую sharpvector основа:

Install-Package SharpVectors

Итак, мой XAML выглядит следующим образом:

<UserControl ...
         xmlns:svgc="http://sharpvectors.codeplex.com/svgc/"
         ...>
    ...
    <svgc:SvgViewbox Margin="5" Height="20" Width="20" Stretch="Uniform" Source="/View/Resources/Icons/Connection.Closed.Black.svg"/>
    ...
</UserControl>

Windows 10 Creators Update (15063) изначально поддерживает образы SVG, хотя и с некоторыми gotchas.

использование так же просто, как установка Source на <Image /> путь к СВГ. Это эквивалентно использованию SvgImageSource следующим образом:

<Image>
    <Image.Source>
        <SvgImageSource UriSource="Assets/svg/icon.svg" />
    </Image.Source>
</Image>

однако изображения SVG загружаются таким образом (через XAML) может загрузить jagged / aliased. Одним из обходных путей является указание RasterizePixelHeight или RasterizePixelWidth значение двойной+ ваш реальный высота/ширина:

<SvgImageSource RasterizePixelHeight="300" RasterizePixelWidth="300" UriSource="Assets/svg/icon.svg" /> <!-- presuming actual height or width is under 150 -->

это можно обойти динамически, создав новый SvgImageSource на ImageOpened событие для базового изображения:

var svgSource = new SvgImageSource(new Uri("ms-appx://" + Icon));
PrayerIcon.ImageOpened += (s, e) =>
{
    var newSource = new SvgImageSource(svgSource.UriSource);
    newSource.RasterizePixelHeight = PrayerIcon.DesiredSize.Height * 2;
    newSource.RasterizePixelWidth = PrayerIcon.DesiredSize.Width * 2;
    PrayerIcon2.Source = newSource;
};
PrayerIcon.Source = svgSource;

сглаживание может быть трудно увидеть на экранах с высоким разрешением, но вот попытка проиллюстрировать это.

это результат кода выше: an Image который использует начальный SvgImageSource, а второй Image под ним, который использует SvgImageSource, созданный в ImageOpened событие:

enter image description here

это взорванный вид верхнего изображения:

enter image description here

тогда как это увеличенный вид нижнего (сглаженного, правильного) изображения:

enter image description here

(вам нужно будет открыть изображения в новой вкладке и просмотреть в полном размере, чтобы оценить разницу)

вы можете использовать полученный xaml из SVG в качестве кисти для рисования на прямоугольнике. Что-то вроде этого:

<Rectangle>
   <Rectangle.Fill>
      --- insert the converted xaml's geometry here ---
   </Rectangle.Fill>
</Rectangle>