WPF Який правильний спосіб використання файлів SVG як піктограм у WPF


78

Хтось може описати рекомендовану крок за кроком процедуру для цього?

РЕДАГУВАТИ:

Крок 1. Перетворити SVG на XAML ... це просто

Крок 2. Що тепер?


11
Вибачте, що я воскресив цю публікацію, але я думаю, що ця інформація має цінність: SVG - це, по суті, поєднання "один на один" із WPF Path. Отже, окрім деяких поверхневих налаштувань розмітки, ви повинні мати можливість просто внести SVG прямо у свою програму WPF. Можливо, вам доведеться розмістити Шлях у полотно, але це все, IMHO.
code4life

Відповіді:


155

Ваша техніка буде залежати від того, який об'єкт 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>

або якщо його слід заповнити, встановіть Заповнення:

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

10
+10 просто витрачаючи час на приклади для всіх випадків. У моєму випадку у мене є полотно, тому я припускаю, що застосовується <Button> <Canvas Height = "100" Width = "100"> <! - Перетворено з SVG, з доповненнями - -> </Canvas> </Button> Але як я можу використовувати це повторно? Я не можу копіювати / вставляти для кожної кнопки, в якій я хочу використовувати зображення svg. Я хотів би визначити його як ресурси у словнику та використовувати як Static / DynamicResource.
NVM

4
Ви не можете використовувати одне полотно в декількох місцях у своєму інтерфейсі, оскільки Visual може мати лише одного батька. Отже, ти зазвичай використовуєш шаблон для цього. Шаблон дозволяє створити окремий екземпляр Canvas кожне місце вам це потрібно: <ResourceDictionary><DataTemplate x:Key="MyIconTemplate"><Canvas ... /></DataTemplate></ResourceDictionary>... <Button><ContentPresenter ContentTemplate="{StaticResource MyIconTemplate}" /></Button>.
Рей Бернс,

1
Більш ефективний , але більш складний підхід полягає у використанні VisualBrush створити картину полотна малювати: <ResourceDictionary><VisualBrush x:Key="MyBrush"><VisualBrush.Visual><Canvas x:Key="MyCanvas" ... /></VisualBrush.Visual></VisualBrush></ResourceDictionary>... <Button><Rectangle Fill="{StaticResource MyBrush}" Width="..." Height="..." /></Button>. Це складніше, оскільки ви також повинні переконатися, що полотно вимірюється / упорядковано, і ви повинні жорстко кодувати ширину / висоту (або використовувати шаблон для прямокутника).
Рей Бернс,

Ага !!! Я знав, що не можу використовувати одне і те ж полотно двічі безпосередньо, тому відповідь ще не прийнято. Дуже дякую.
NVM

1
Отже, в основному для кожного з цих елементів - наприклад, Canvasоб’єкта, куди я можу поставити SVG? Це важливо, тому що всі мої SVG знаходяться у статичних ресурсах, і мені потрібно їх вбудовувати ...
code4life

52

Встановіть бібліотеку SharpVectors

Install-Package SharpVectors

Додайте наступне в XAML

<UserControl xmlns:svgc="http://sharpvectors.codeplex.com/svgc">
    <svgc:SvgViewbox Source="/Icons/icon.svg"/>
</UserControl>

6
Чи краще вбудовувати XAML Imges у програму або використовувати такий підхід?
MyOwnWay

У мене дуже добре працює ... із самородками та всім іншим. Мені довелося правильно зробити svg з кольоровою інформацією, але як тільки це було вирішено, вони не здаються чорними, але виглядають добре.
kfn

1
Ось як ви можете прив'язати до джерела AttachedProperty з sharpvectors: stackoverflow.com/a/35088090/828184
CodingYourLife

Оновлення на 2020 рік. Нова версія використовує SharpVectors. Перезавантажено
Енді Брехем,

1
Листопад 2020: 1.7.0 створив виняток NullReference для вихідної властивості SvgViewbox незалежно від вмісту. Понижено до версії 1.6.0 (SharpVectors.Reloaded), вона працює там.
Володимир Котило

7

Windows 10 build 15063 "Creators Update" спочатку підтримує зображення 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, які взаємодіють із користувацькими даними або системою (наприклад, завантаження зображень з диска у веб-перегляді UWP Windows 10 або використання API-повідомлень тостів для показу тостів), вам також потрібно пов’язати свою програму WPF з ідентифікацією пакета, як показано тут (надзвичайно простіше у Visual Studio 2019). Однак це не повинно бути необхідним для використання Windows.UI.Xaml.Media.Imaging.SvgImageSourceкласу.

Використання (якщо ви користуєтеся UWP або дотримувались наведених вище вказівок і додали підтримку острова XAML під WPF), це просто, як встановити Source a <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;

Псевдонім може бути важко побачити на екранах, що не мають високих точок на дюйм, але ось спробу це проілюструвати.

Це результат наведеного вище коду: an, Imageякий використовує початковий код SvgImageSource, а другий Imageпід ним використовує SvgImageSource, створений уImageOpened події:

введіть тут опис зображення

Це підірваний вид верхнього зображення:

введіть тут опис зображення

Тоді як це підірваний вигляд нижнього (згладженого, правильного) зображення:

введіть тут опис зображення

(вам потрібно буде відкрити зображення на новій вкладці та переглянути в повному розмірі, щоб оцінити різницю)


14
SvgImageSource - це бібліотека UWP, а не WPF, на жаль.
adam_0

5
Це UWP, а не WPF; Ви плутаєте XAML
juFo

3

Ви можете використовувати отриманий xaml із SVG як пензлик для малювання на прямокутнику. Щось на зразок цього:

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

3
Та ж проблема, що і в першій відповіді. Я не хочу копіювати вставлення щоразу, коли хочу використовувати той самий svg.
NVM


1

Інша альтернатива - dotnetprojects SVGImage

Це дозволяє власне використання файлів .svg безпосередньо в xaml.

Приємна частина - це лише одна збірка, яка становить близько 100 тис. На відміну від різких векторів, який набагато більший за будь-які файли.

Використання:

...
xmlns:svg1="clr-namespace:SVGImage.SVG;assembly=DotNetProjects.SVGImage"
...
<svg1:SVGImage Name="mySVGImage" Source="/MyDemoApp;component/Resources/MyImage.svg"/>
...

Це все.

Подивитися:


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.