Saltar al contenido

WPF ¿Cuál es la forma correcta de usar archivos SVG como iconos en WPF?

Solución:

Su técnica dependerá del objeto XAML que produzca su convertidor de SVG a XAML. ¿Produce un dibujo? ¿Una imagen? ¿Una cuadrícula? ¿Un lienzo? ¿Un sendero? ¿Una geometría? En cada caso tu técnica será diferente.

En los ejemplos a continuación, asumiré que está usando su icono en un botón, que es el escenario más común, pero tenga en cuenta que las mismas técnicas funcionarán para cualquier ContentControl.

Usar un dibujo como icono

Para usar un dibujo, pinte un rectángulo de tamaño apropiado con un DrawingBrush:

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

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

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

Usar una imagen como icono

Una imagen se puede utilizar directamente:

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

Usar una cuadrícula como icono

Una cuadrícula se puede utilizar directamente:

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

O puede incluirlo en un Viewbox si necesita controlar el tamaño:

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

Usar un lienzo como icono

Esto es como usar una imagen o cuadrícula, pero dado que un lienzo no tiene un tamaño fijo, debe especificar la altura y el ancho (a menos que ya estén configurados por el convertidor SVG):

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

Usar una ruta como icono

Puede usar una ruta, pero debe establecer el trazo o el relleno explícitamente:

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

o

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

Usar una geometría como icono

Puede utilizar una ruta para dibujar su geometría. Si debe ser acariciado, configure el Trazo:

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

o si debe llenarse, configure el Relleno:

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

Cómo enlazar datos

Si está haciendo la conversión SVG -> XAML en el código y desea que el XAML resultante aparezca usando el enlace de datos, use uno de los siguientes:

Encuadernación de un dibujo:

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

Encuadernación de una imagen:

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

Vincular una cuadrícula:

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

Vincular una cuadrícula en un cuadro de visualización:

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

Encuadernación de un lienzo:

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

Vinculando un camino:

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

Encuadernación de una geometría:

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

Instale la biblioteca SharpVectors

Install-Package SharpVectors

Agregue lo siguiente en XAML

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

Windows 10 build 15063 “Creators Update” admite de forma nativa imágenes SVG (aunque con algunas trampas) para aplicaciones UWP / UAP destinadas a Windows 10.

Si su aplicación es una aplicación WPF en lugar de una UWP / UAP, aún puede usar esta API (después de pasar por una gran cantidad de aros): Windows 10 build 17763 “October 2018 Update” introdujo el concepto de islas XAML (como ” tecnología de vista previa “pero creo que está permitida en la tienda de aplicaciones; en todos los casos, con Windows 10 build 18362” Actualización de mayo de 2019 “, las islas XAML ya no son una función de vista previa y son totalmente compatibles), lo que le permite usar las API y los controles de UWP en su WPF. aplicaciones.

Primero debe agregar las referencias a las API de WinRT y usar ciertas API de Windows 10 que interactúan con los datos del usuario o el sistema (por ejemplo, cargar imágenes desde el disco en una vista web de Windows 10 UWP o usar la API de notificación de tostadas para mostrar brindis), también necesita asociar su aplicación WPF con una identidad de paquete, como se muestra aquí (inmensamente más fácil en Visual Studio 2019). Esto no debería ser necesario para usar el Windows.UI.Xaml.Media.Imaging.SvgImageSource clase, sin embargo.

El uso (si está en UWP o ha seguido las instrucciones anteriores y ha agregado compatibilidad con la isla XAML en WPF) es tan simple como configurar el Source por un <Image /> a la ruta al SVG. Eso es equivalente a usar SvgImageSource, como sigue:

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

Sin embargo, las imágenes SVG cargadas de esta manera (a través de XAML) pueden cargarse dentadas o con alias. Una solución es especificar un RasterizePixelHeight o RasterizePixelWidth valor que es el doble + su altura / ancho real:

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

Esto se puede solucionar dinámicamente creando un nuevo SvgImageSource en el ImageOpened evento para la imagen base:

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;

El alias puede ser difícil de ver en pantallas que no son de alta resolución, pero aquí hay un intento de ilustrarlo.

Este es el resultado del código anterior: un Image que usa la inicial SvgImageSourcey un segundo Image debajo de él que utiliza el SvgImageSource creado en el ImageOpened evento:

ingrese la descripción de la imagen aquí

Esta es una vista ampliada de la imagen superior:

ingrese la descripción de la imagen aquí

Considerando que esta es una vista ampliada de la imagen inferior (suavizada, correcta):

ingrese la descripción de la imagen aquí

(deberá abrir las imágenes en una nueva pestaña y verlas en tamaño completo para apreciar la diferencia)

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)


Tags : / /

Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *