WPF What is the correct way to use SVG files as icons in WPF

Can someone describe the recommended Step by Step procedure for this?

EDIT:

Step 1. Convert SVG to XAML ... thats easy

Step2. Now what?

+63
wpf svg
Aug 19 '10 at 21:23
source share
5 answers

Your technique will depend on which XAML object your SVG uses for the XAML converter. Does it make a drawing? Picture? Grid? Canvas? Way? Geometry? In each case, your technique will be different.

In the examples below, I assume that you are using your icon on a button, which is the most common scenario, but note that the same methods will work for any ContentControl.

Using a drawing as an icon

To use Drawing, draw a rectangle of a suitable size using the DrawingBrush:

<Button> <Rectangle Width="100" Height="100"> <Rectangle.Fill> <DrawingBrush> <DrawingBrush.Drawing> <Drawing ... /> <!-- Converted from SVG --> </DrawingBrush.Drawing> </DrawingBrush> </Rectangle.Fill> </Rectangle> </Button> 

Using an image as an icon

The image can be used directly:

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

Using the grid as an icon

The grid can be used directly:

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

Or you can include it in the viewport if you need to control the size:

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

Using canvas as an icon

This is similar to using an image or grid, but since the canvas size does not have a fixed size, you need to specify the height and width (if they are not already set by the SVG converter):

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

Using path as icon

You can use the Path, but you must set the stroke or fill explicitly:

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

or

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

Using geometry as an icon

You can use the Path to draw your geometry. If it should be stroked, set the Stroke:

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

or if it should be filled, install Fill:

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

How to bind data

If you are converting SVG โ†’ XAML in code and want the resulting XAML to appear using data binding, use one of the following actions:

Linking Pattern:

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

Image Linking:

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

Mesh Binding:

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

Grid binding in viewport:

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

Canvas binding:

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

Path binding:

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

Geometry Linking:

 <Button> <Path Width="100" Height="100" Data="{Binding Geometry}" /> </Button> 
+125
Aug 20 '10 at 5:56
source share

I found a better way to use the SVG icon in WPF. I am using sharpvector framework:

 Install-Package SharpVectors 

So my XAML looks like this:

 <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> 
+40
Feb 28 '14 at 22:53
source share

Windows 10 build 15063 Creator Update initially supports SVG images (albeit with some bugs) for Windows 10-oriented UWP / UAP applications.

If your application is a WPF application, not UWP / UAP, you can still use this API (after a few jumps): Windows 10 build 17763 โ€œOctober 2018 Updateโ€ introduced the concept of the XAML islands (as โ€œpreview technology, but I consider that it is allowed in the application store; in all cases with Windows 10 build 18362 "Update as of May 2019" the XAML islands are no longer a preview function and are fully supported), which allows the use of APIs and UWP controls in WPF Applications.

First you need to add links to the WinRT APIs and use certain Windows 10 APIs that interact with user data or the system (for example, loading images from a disk in the Windows 10 UWP web view or using the toast notification API to display toasts), you also need to associate your WPF application with the package identifier as shown here (this is significantly easier in Visual Studio 2019). It should not be necessary to use the Windows.UI.Xaml.Media.Imaging.SvgImageSource class.

Usage (if you use UWP or follow the instructions above and add support for XAML islands in WPF) is as simple as setting Source for the <Image/> path to SVG. This is equivalent to using SvgImageSource as follows:

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

However, SVG images uploaded this way (via XAML) can be uploaded with notches / aliases . One workaround is to specify a RasterizePixelHeight or RasterizePixelWidth value that double + matches your actual height / width:

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

This can be circumvented dynamically by creating a new SvgImageSource in the ImageOpened event for the base image:

 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 alias can be difficult to see on screens without high resolution, but here's an attempt to illustrate this.

This is the result of the above code: Image that uses the original SvgImageSource , and the second Image below it that uses the SvgImageSource created in the ImageOpened event:

enter image description here

This is an exploded view of the top image:

enter image description here

Whereas this is an enlarged image of the bottom (smoothed, correct) image:

enter image description here

(you need to open the images in a new tab and view in full size to appreciate the difference)

+5
Jul 05 '17 at 21:12
source share

You can use the resulting xaml from SVG as a drawing brush on a rectangle. Something like that:

 <Rectangle> <Rectangle.Fill> --- insert the converted xaml geometry here --- </Rectangle.Fill> </Rectangle> 
+3
Aug 20 '10 at 2:31
source share

Use the extensions SvgImage or SvgImageConverter, SvgImageConverter supports binding. See the following link for samples showing both extensions.

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

0
Jul 06 '19 at 3:07
source share



All Articles