web-dev-qa-db-fra.com

WPF Quelle est la bonne façon d'utiliser les fichiers SVG comme icônes dans WPF

Quelqu'un peut-il décrire une procédure étape par étape recommandée pour ce faire?

MODIFIER:

Étape 1. Convertir SVG en XAML ... c'est facile

Étape 2. Maintenant quoi?

61
NVM

Votre technique dépendra de l'objet XAML produit par votre convertisseur SVG vers XAML. Produit-il un dessin? Une image? Une grille? Une toile? Un chemin? Une géométrie? Dans chaque cas, votre technique sera différente.

Dans les exemples ci-dessous, je suppose que vous utilisez votre icône sur un bouton, ce qui est le scénario le plus courant, mais notez que les mêmes techniques fonctionneront pour n'importe quel ContentControl.

tilisation d'un dessin comme icône

Pour utiliser un dessin, peignez un rectangle de taille appropriée avec un DrawingBrush:

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

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

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

tilisation d'une image comme icône

Une image peut être utilisée directement:

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

tilisation d'une grille comme icône

Une grille peut être utilisée directement:

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

Ou vous pouvez l'inclure dans une Viewbox si vous avez besoin de contrôler la taille:

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

tilisation d'un canevas comme icône

C'est comme utiliser une image ou une grille, mais comme un canevas n'a pas de taille fixe, vous devez spécifier la hauteur et la largeur (sauf si elles sont déjà définies par le convertisseur SVG):

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

tiliser un chemin comme icône

Vous pouvez utiliser un chemin, mais vous devez définir le trait ou remplir explicitement:

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

ou

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

tilisation d'une géométrie comme icône

Vous pouvez utiliser un chemin pour dessiner votre géométrie. S'il doit être caressé, réglez le trait:

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

ou s'il doit être rempli, définissez le remplissage:

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

Comment lier les données

Si vous effectuez la conversion SVG -> XAML dans le code et souhaitez que le XAML résultant apparaisse à l'aide de la liaison de données, utilisez l'une des méthodes suivantes:

Relier un dessin:

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

Relier une image:

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

Liaison d'une grille:

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

Liaison d'une grille dans une fenêtre d'affichage:

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

Relier une toile:

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

Relier un chemin:

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

Liaison d'une géométrie:

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

J'ai trouvé le meilleur moyen d'utiliser l'icône svg dans WPF. J'utilise sharpvector framework:

Install-Package SharpVectors

Mon XAML ressemble donc à ceci:

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

Windows 10 build 15063 "Creators Update" prend en charge nativement les images SVG (bien qu'avec certains gotchas) aux applications UWP/UAP ciblant Windows 10.

Si votre application est une application WPF plutôt qu'un UWP/UAP, vous pouvez toujours utiliser cette API (après avoir parcouru un certain nombre de cercles): Windows 10 build 17763 "October 2018 Update" introduit le concept d'îlots XAML (en tant que technologie "d'aperçu" mais je crois autorisé dans l'App Store; dans tous les cas, avec Windows 10 build 18362 "Mise à jour de mai 2019", les îlots XAML ne sont plus une fonctionnalité d'aperçu et sont entièrement pris en charge) vous permettant utiliser les API et les contrôles UWP dans vos applications WPF.

Vous devez d'abord ajouter les références aux API WinRT , et utiliser certaines API Windows 10 qui interagissent avec les données utilisateur ou le système (par exemple, chargement d'images à partir du disque dans une vue Web Windows 10 UWP ou en utilisant l'API de notification de toast pour afficher les toasts), vous devez également associer votre application WPF à une identité de package, comme indiqué ici (beaucoup plus facile dans Visual Studio 2019). Cela ne devrait pas être nécessaire pour utiliser le Windows.UI.Xaml.Media.Imaging.SvgImageSource classe, cependant.

L'utilisation (si vous êtes sur UWP ou si vous avez suivi les instructions ci-dessus et ajouté la prise en charge de l'îlot XAML sous WPF) est aussi simple que de définir le Source pour un <Image /> vers le chemin vers le SVG. Cela équivaut à utiliser SvgImageSource, comme suit:

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

Cependant, les images SVG chargées de cette manière (via XAML) peuvent charger des créneaux/des alias . Une solution consiste à spécifier une valeur RasterizePixelHeight ou RasterizePixelWidth double + votre hauteur/largeur réelle:

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

Cela peut être contourné dynamiquement en créant un nouveau SvgImageSource dans l'événement ImageOpened pour l'image de 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;

L'aliasing peut être difficile à voir sur les écrans non à haute résolution, mais voici une tentative pour l'illustrer.

C'est le résultat du code ci-dessus: un Image qui utilise le SvgImageSource initial, et un second Image en dessous qui utilise le SvgImageSource créé dans le ImageOpened un événement:

enter image description here

Voici une vue agrandie de l'image du haut:

enter image description here

Alors que c'est une vue agrandie de l'image du bas (anticrénelage, correcte):

enter image description here

(vous devrez ouvrir les images dans un nouvel onglet et les afficher en taille réelle pour apprécier la différence)

5
Mahmoud Al-Qudsi

Vous pouvez utiliser le xaml résultant du SVG comme pinceau de dessin sur un rectangle. Quelque chose comme ça:

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

Utilisez les extensions SvgImage ou SvgImageConverter, SvgImageConverter prend en charge la liaison. Voir le lien suivant pour des exemples illustrant les deux extensions.

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

0
Paulus