webentwicklung-frage-antwort-db.com.de

WPF Wie werden SVG-Dateien in WPF korrekt als Symbole verwendet?

Kann jemand eine empfohlene schrittweise Vorgehensweise beschreiben, um dies zu tun?

BEARBEITEN:

Schritt 1. SVG in XAML konvertieren ... das ist einfach

Schritt 2. Was jetzt?

61
NVM

Ihre Technik hängt davon ab, welches XAML-Objekt Ihr SVG-XAML-Konverter erzeugt. Erzeugt es eine Zeichnung? Ein Bild? Ein Gitter? Eine Leinwand? Ein Weg? Eine Geometrie? In jedem Fall ist Ihre Technik anders.

In den folgenden Beispielen wird davon ausgegangen, dass Sie Ihr Symbol auf einer Schaltfläche verwenden. Dies ist das häufigste Szenario. Beachten Sie jedoch, dass für alle ContentControl-Elemente dieselben Techniken verwendet werden.

Verwenden einer Zeichnung als Symbol

Um eine Zeichnung zu verwenden, malen Sie mit einem DrawingBrush ein Rechteck in der richtigen Größe:

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

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

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

Verwenden eines Bildes als Symbol

Ein Bild kann direkt verwendet werden:

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

Verwenden eines Rasters als Symbol

Ein Raster kann direkt verwendet werden:

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

Oder Sie können es in eine Viewbox einfügen, wenn Sie die Größe steuern müssen:

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

Verwenden eines Canvas als Symbol

Dies entspricht der Verwendung eines Bilds oder Rasters. Da eine Leinwand jedoch keine feste Größe hat, müssen Sie Höhe und Breite angeben (sofern diese nicht bereits vom SVG-Konverter festgelegt wurden):

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

Pfad als Symbol verwenden

Sie können einen Pfad verwenden, aber Sie müssen den Strich festlegen oder explizit ausfüllen:

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

oder

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

Verwenden einer Geometrie als Symbol

Sie können einen Pfad verwenden, um Ihre Geometrie zu zeichnen. Wenn es gestrichen werden soll, stellen Sie den Strich ein:

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

oder wenn es gefüllt werden soll, setze die Füllung:

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

Wie man Daten bindet

Wenn Sie die SVG -> XAML-Konvertierung im Code durchführen und möchten, dass die resultierende XAML mithilfe der Datenbindung angezeigt wird, verwenden Sie eine der folgenden Methoden:

Eine Zeichnung binden:

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

Ein Bild binden:

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

Gitter binden:

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

Binden eines Rasters in einer Viewbox:

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

Eine Leinwand binden:

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

Einen Pfad binden:

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

Binden einer Geometrie:

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

Ich habe den besten Weg gefunden, um svg icon in WPF zu verwenden. Ich benutze sharpvector Framework:

Install-Package SharpVectors

Mein XAML sieht also so aus:

<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" unterstützt nativ SVG-Bilder (wenn auch mit einigen Fallstricken) für UWP/UAP-Anwendungen, die auf Windows 10 abzielen.

Wenn Ihre Anwendung eine WPF-Anwendung und keine UWP/UAP-Anwendung ist, können Sie diese API weiterhin verwenden (nachdem Sie eine ganze Reihe von Rahmen durchlaufen haben): Einführung von Windows 10 Build 17763 "October 2018 Update" Das Konzept der XAML-Inseln (als "Vorschau" -Technologie, aber ich glaube, im App Store erlaubt; in allen Fällen sind mit Windows 10 Build 18362 "Mai 2019 Update" XAML-Inseln keine Vorschaufunktion mehr und werden voll unterstützt) Verwenden von UWP-APIs und Steuerelementen in Ihren WPF-Anwendungen.

Sie müssen zuerst Verweise auf die WinRT-APIs hinzufügen und bestimmte Windows 10-APIs verwenden, die mit Benutzerdaten oder dem System interagieren (z. B. Laden von Bildern von der Festplatte in In einer Windows 10 UWP-Webansicht oder mithilfe der Toastbenachrichtigungs-API zum Anzeigen von Toasts müssen Sie Ihrer WPF-Anwendung auch eine Paketidentität zuordnen wie hier gezeigt (in Visual Studio 2019 ungemein einfacher). Dies sollte nicht notwendig sein, um die Windows.UI.Xaml.Media.Imaging.SvgImageSource Klasse, obwohl.

Die Verwendung (wenn Sie UWP verwenden oder die obigen Anweisungen befolgt und XAML-Island-Unterstützung unter WPF hinzugefügt haben) ist so einfach wie das Festlegen von Source für ein <Image /> zum Pfad zur SVG. Dies entspricht der Verwendung von SvgImageSource wie folgt:

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

Auf diese Weise geladene SVG-Bilder (über XAML) können gezackte/verzerrte Bilder laden . Eine Problemumgehung besteht darin, einen Wert RasterizePixelHeight oder RasterizePixelWidth anzugeben, der doppelt so groß ist wie Ihre tatsächliche Höhe/Breite:

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

Dies kann dynamisch umgangen werden, indem im Ereignis SvgImageSource für das Basisimage ein neues ImageOpened erstellt wird:

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;

Das Aliasing ist auf nicht hochauflösenden Bildschirmen möglicherweise schwer zu erkennen, aber hier ist ein Versuch, es zu veranschaulichen.

Dies ist das Ergebnis des obigen Codes: Ein Image, das das ursprüngliche SvgImageSource verwendet, und ein zweites Image darunter, das die in ImageOpened erstellte SvgImageSource verwendet. ] Veranstaltung:

enter image description here

Dies ist eine vergrößerte Ansicht des oberen Bildes:

enter image description here

Während dies eine vergrößerte Ansicht des unteren (antialias, korrekten) Bildes ist:

enter image description here

(Sie müssen die Bilder in einem neuen Tab öffnen und in voller Größe anzeigen, um den Unterschied zu erkennen.)

5

Sie können das resultierende XAML aus der SVG-Datei als Zeichenpinsel für ein Rechteck verwenden. Etwas wie das:

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

Verwenden Sie die Erweiterungen SvgImage oder SvgImageConverter, der SvgImageConverter unterstützt die Bindung. Unter dem folgenden Link finden Sie Beispiele für beide Erweiterungen.

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

0
Paulus