WPF Как правильно использовать файлы SVG в качестве значков в WPF? - PullRequest
61 голосов
/ 20 августа 2010

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

РЕДАКТИРОВАТЬ:

Шаг1.Конвертировать SVG в XAML ... это просто

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

Ответы [ 5 ]

120 голосов
/ 20 августа 2010

Ваша техника будет зависеть от того, какой объект 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>

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

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

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

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

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

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

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

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

или

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

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

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

<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>
38 голосов
/ 01 марта 2014

Я нашел лучший способ использовать иконку 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>
5 голосов
/ 06 июля 2017

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, которое будет удваиваться + ваша фактическая высота / ширина:

<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

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

enter image description here

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

3 голосов
/ 20 августа 2010

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

<Rectangle>
   <Rectangle.Fill>
      --- insert the converted xaml's geometry here ---
   </Rectangle.Fill>
</Rectangle>
0 голосов
/ 06 июля 2019

Используйте расширения SvgImage или SvgImageConverter, SvgImageConverter поддерживает привязку.См. Следующую ссылку для образцов, демонстрирующих оба расширения.

https://github.com/ElinamLLC/SharpVectors/tree/master/TutorialSamples/ControlSamplesWpf

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