web-dev-qa-db-de.com

WPF-Bildressourcen

Ich komme hauptsächlich aus dem Web und ein bisschen Windows Forms Hintergrund. Für ein neues Projekt werden wir WPF verwenden. Die WPF-Anwendung benötigt zur Veranschaulichung 10 - 20 kleine Symbole und Bilder. Ich denke darüber nach, diese in der Versammlung als eingebettete Ressourcen zu speichern. Ist das der richtige Weg?

Wie gebe ich in XAML an, dass ein Image-Steuerelement das Image von einer eingebetteten Ressource laden soll?

385
driis

Wenn Sie das Bild an mehreren Stellen verwenden, sollten Sie die Bilddaten nur einmal in den Speicher laden und dann für alle Image -Elemente freigeben.

Erstellen Sie dazu irgendwo ein BitmapSource als Ressource:

<BitmapImage x:Key="MyImageSource" UriSource="../Media/Image.png" />

Verwenden Sie dann in Ihrem Code Folgendes:

<Image Source="{StaticResource MyImageSource}" />

In meinem Fall stellte ich fest, dass ich die Image.png -Datei so einstellen musste, dass sie die Build-Aktion Resource und nicht nur Content enthält. Dadurch wird das Image in Ihrer kompilierten Assembly gespeichert.

458
Drew Noakes

Ich fand, dass die beste Methode für die Verwendung von Bildern, Videos usw. ist:

  • Ändern Sie Ihre Dateien "Build action" zu "Content". Stellen Sie sicher, dass Sie In Erstellungsverzeichnis kopieren .
    • Befindet sich im Kontextmenü des Projektmappen-Explorers.
  • Bildquelle im folgenden Format:
    • "/ " YourAssemblyName "; Komponente /" YourPath "/ " YourImage.png " "

Beispiel

<Image Source="/WPFApplication;component/Images/Start.png" />

Leistungen:

  • Dateien werden nicht in die Assembly eingebettet.
    • Der Ressourcenmanager wird einige Speicherüberlaufprobleme mit zu vielen Ressourcen (zum Zeitpunkt der Erstellung) auslösen.
  • Kann zwischen Baugruppen aufgerufen werden.
165
Nuno Rodrigues

Einige Leute fragen im Code danach und bekommen keine Antwort.

Nachdem ich viele Stunden lang gesucht hatte, fand ich eine sehr einfache Methode, ich fand kein Beispiel und teile meine hier, die mit Bildern arbeitet. (meins war ein .gif)

Zusammenfassung:

Es gibt einen BitmapFrame zurück, den ImageSource "Ziele" zu mögen scheinen.

Verwenden:

doGetImageSourceFromResource ("[YourAssemblyNameHere]", "[YourResourceNameHere]");

Methode:

static internal ImageSource doGetImageSourceFromResource(string psAssemblyName, string psResourceName)
{
    Uri oUri = new Uri("pack://application:,,,/" +psAssemblyName +";component/" +psResourceName, UriKind.RelativeOrAbsolute);
    return BitmapFrame.Create(oUri);
}

Lernerfahrungen:

Meiner Erfahrung nach ist der Pack-String nicht das Problem. Überprüfen Sie Ihre Streams, und vor allem, wenn beim ersten Lesen der Zeiger auf das Ende der Datei gesetzt wurde und Sie ihn vor dem erneuten Lesen auf Null zurücksetzen müssen.

Ich hoffe, das erspart Ihnen die vielen Stunden, die ich mir für dieses Stück gewünscht habe!

45
Craig

Im Code zum Laden einer Ressource in die ausführende Assembly, in der sich mein Image Freq.png im Ordner Icons befand und als Resource definiert wurde:

this.Icon = new BitmapImage(new Uri(@"pack://application:,,,/" 
    + Assembly.GetExecutingAssembly().GetName().Name 
    + ";component/" 
    + "Icons/Freq.png", UriKind.Absolute)); 

Ich habe auch eine Funktion gemacht:

/// <summary>
/// Load a resource WPF-BitmapImage (png, bmp, ...) from embedded resource defined as 'Resource' not as 'Embedded resource'.
/// </summary>
/// <param name="pathInApplication">Path without starting slash</param>
/// <param name="Assembly">Usually 'Assembly.GetExecutingAssembly()'. If not mentionned, I will use the calling Assembly</param>
/// <returns></returns>
public static BitmapImage LoadBitmapFromResource(string pathInApplication, Assembly assembly = null)
{
    if (Assembly == null)
    {
        Assembly = Assembly.GetCallingAssembly();
    }

    if (pathInApplication[0] == '/')
    {
        pathInApplication = pathInApplication.Substring(1);
    }
    return new BitmapImage(new Uri(@"pack://application:,,,/" + Assembly.GetName().Name + ";component/" + pathInApplication, UriKind.Absolute)); 
}

Verwendung (Annahme, dass Sie die Funktion in eine ResourceHelper-Klasse einfügen):

this.Icon = ResourceHelper.LoadBitmapFromResource("Icons/Freq.png");

Hinweis : Siehe MSDN Pack-URIs in WPF :
pack://application:,,,/ReferencedAssembly;component/Subfolder/ResourceFile.xaml

39
Eric Ouellet

Ja, das ist der richtige Weg.

Sie können das Bild in der Ressourcendatei verwenden, indem Sie nur den Pfad verwenden:

<Image Source="..\Media\Image.png" />

Sie müssen die Build-Aktion der Image-Datei auf "Ressource" setzen.

38
ema

Vollständige Beschreibung der Verwendung von Ressourcen: WPF-Anwendungsressourcen-, Inhalts- und Datendateien

Lesen Sie "Packen von URIs in WPF", um zu erfahren, wie Sie auf diese verweisen.

Kurz gesagt, es gibt sogar Möglichkeiten, Ressourcen von referenzierten/referenzierenden Assemblys zu referenzieren.

13
techfan
  1. Visual Studio 2010 Professional SP1.
  2. .NET Framework 4-Clientprofil.
  3. PNG-Bild als Ressource für Projekteigenschaften hinzugefügt.
  4. Neue Datei im Ressourcenordner wird automatisch erstellt.
  5. Build-Aktion auf Ressource festgelegt.

Das hat bei mir funktioniert:

<BitmapImage x:Key="MyImageSource" UriSource="Resources/Image.png" />
4
JoanComasFdz

Ja, das ist der richtige Weg. Sie können Bilder in der Ressourcendatei über einen Pfad verwenden:

<StackPanel Orientation="Horizontal">
    <CheckBox  Content="{Binding Nname}" IsChecked="{Binding IsChecked}"/>
    <Image Source="E:\SWorking\SharePointSecurityApps\SharePointSecurityApps\SharePointSecurityApps.WPF\Images\sitepermission.png"/>
    <TextBlock Text="{Binding Path=Title}"></TextBlock>
</StackPanel>
3
Sanjay Ranavaya

Wenn Sie Blend verwenden, um es besonders einfach zu machen und keine Probleme zu haben, den richtigen Pfad für das Source Attribut zu ermitteln Ziehen Sie das Bild einfach aus dem Projektfenster auf den Designer und legen Sie es dort ab.

3
user42467