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

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

ИЗМЕНИТЬ:

Шаг1. Преобразование SVG в XAML... thats easy

Step2. Теперь что?

Ответ 1

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

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

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

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

<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>

Ответ 2

Я нашел лучший способ использовать иконку SVG в WPF. Я использую sharpvector framework:

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>

Ответ 3

Windows 10 build 15063 "Обновление создателей" изначально поддерживает образы SVG (хотя и с некоторыми ошибками) для приложений UWP/UAP, ориентированных на Windows 10.

Если ваше приложение является приложением WPF, а не UWP/UAP, вы все равно можете использовать этот API (после нескольких скачков): Windows 10 build 17763 "Обновление за октябрь 2018" представило концепцию островов XAML (как " технология предварительного просмотра, но я считаю, что она разрешена в магазине приложений; во всех случаях с Windows 10 build 18362 "Обновление от мая 2019" XAML-острова больше не являются функцией предварительного просмотра и полностью поддерживаются), что позволяет использовать API-интерфейсы и элементы управления UWP в WPF Приложения.

Сначала необходимо добавить ссылки на API-интерфейсы WinRT и использовать определенные API-интерфейсы Windows 10, которые взаимодействуют с пользовательскими данными или системой (например, загрузка изображений с диска в веб-представлении Windows 10 UWP или использование API уведомлений о тостах для отображения тостов), вам также необходимо связать ваше приложение WPF с идентификатором пакета, как показано здесь (это значительно проще в Visual Studio 2019). Это не должно быть необходимым для использования класса Windows.UI.Xaml.Media.Imaging.SvgImageSource.

Использование (если вы используете UWP или выполнили указания выше и добавили поддержку островов XAML в WPF) так же просто, как установить Source для <Image/> пути к SVG. Это эквивалентно использованию SvgImageSource следующим образом:

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

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

<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;

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

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

enter image description here

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

enter image description here

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

enter image description here

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

Ответ 4

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

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

Ответ 6

Мы можем напрямую использовать код пути из кода SVG:

    <Path>
        <Path.Data>
            <PathGeometry Figures="M52.8,105l-1.9,4.1c ...