Frage

Ich versuche, eine Liste benutzerdefinierter Objekte wie folgt an ein WPF-Image zu binden:

<Image>
    <Image.Source>
        <BitmapImage UriSource="{Binding Path=ImagePath}" />
    </Image.Source>
</Image>

Aber es funktioniert nicht.Dies ist der Fehler, den ich erhalte:

„Eigenschaft ‚UriSource‘ oder Eigenschaft ‚StreamSource‘ muss festgelegt werden.“

Was vermisse ich?

War es hilfreich?

Lösung

WPF verfügt über integrierte Konverter für bestimmte Typen.Wenn Sie die Bilder binden Source Eigentum an a string oder Uri Wert, unter der Haube verwendet WPF einen ImageSourceConverter um den Wert in einen umzuwandeln ImageSource.

Also

<Image Source="{Binding ImageSource}"/>

würde funktionieren, wenn die ImageSource-Eigenschaft eine Zeichenfolgendarstellung eines gültigen URI für ein Bild wäre.

Sie können natürlich Ihren eigenen Bindungskonverter erstellen:

public class ImageConverter : IValueConverter
{
    public object Convert(
        object value, Type targetType, object parameter, CultureInfo culture)
    {
        return new BitmapImage(new Uri(value.ToString()));
    }

    public object ConvertBack(
        object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotSupportedException();
    }
}

und benutze es so:

<Image Source="{Binding ImageSource, Converter={StaticResource ImageConverter}}"/>

Andere Tipps

Dieser Artikel von Atul Gupta enthält Beispielcode, der mehrere Szenarien abdeckt:

  1. Reguläre Ressourcenbildbindung an die Source-Eigenschaft in XAML
  2. Bindendes Ressourcenbild, aber vom Code dahinter
  3. Binden Sie das Ressourcenbild im Code dahinter mithilfe von Application.GetResourceStream
  4. Laden des Bildes aus dem Dateipfad über den Speicherstream (dasselbe gilt beim Laden von Blog-Bilddaten aus der Datenbank)
  5. Laden des Bildes aus dem Dateipfad, jedoch unter Verwendung der Bindung an eine Dateipfadeigenschaft
  6. Binden von Bilddaten an ein Benutzersteuerelement, das intern über eine Abhängigkeitseigenschaft über die Bildsteuerung verfügt
  7. Wie Punkt 5, aber stellen Sie außerdem sicher, dass die Datei nicht auf der Festplatte gesperrt wird

Sie können auch einfach das Quellattribut festlegen, anstatt die untergeordneten Elemente zu verwenden.Dazu muss Ihre Klasse das Bild als Bitmap-Bild zurückgeben.Hier ist ein Beispiel dafür, wie ich es gemacht habe

<Image Width="90" Height="90" 
       Source="{Binding Path=ImageSource}"
       Margin="0,0,0,5" />

Und die Klasseneigenschaft ist einfach diese

public object ImageSource {
    get {
        BitmapImage image = new BitmapImage();

        try {
            image.BeginInit();
            image.CacheOption = BitmapCacheOption.OnLoad;
            image.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
            image.UriSource = new Uri( FullPath, UriKind.Absolute );
            image.EndInit();
        }
        catch{
            return DependencyProperty.UnsetValue;
        }

        return image;
    }
}

Ich vermute, dass es etwas aufwändiger ist als der Wertkonverter, aber es ist eine andere Option.

Sie benötigen eine Implementierung von IValueConverter Schnittstelle, die die URL in ein Bild umwandelt.Ihre Convert-Implementierung von IValueConverter sieht in etwa so aus:

BitmapImage image = new BitmapImage();
image.BeginInit();
image.UriSource = new Uri(value as string);
image.EndInit();

return image;

Dann müssen Sie den Konverter in Ihrer Bindung verwenden:

<Image>
    <Image.Source>
        <BitmapImage UriSource="{Binding Path=ImagePath, Converter=...}" />
    </Image.Source>
</Image>

Das Problem mit der hier gewählten Antwort besteht darin, dass beim Hin- und Hernavigieren der Konverter jedes Mal ausgelöst wird, wenn die Seite angezeigt wird.

Dadurch werden ständig neue Dateihandles erstellt und jeder Versuch, die Datei zu löschen, blockiert, da sie noch verwendet wird.Dies kann mithilfe des Process Explorer überprüft werden.

Wenn die Bilddatei irgendwann gelöscht werden könnte, könnte ein Konverter wie dieser verwendet werden:Verwenden von XAML zum Binden an ein System.Drawing.Image in ein System.Windows.Image-Steuerelement

Der Nachteil dieser Memory-Stream-Methode besteht darin, dass die Bilder jedes Mal geladen und dekodiert werden und kein Caching stattfinden kann:"Um zu verhindern, dass Bilder mehr als einmal dekodiert werden, weisen Sie das Bild zu. Suchen Sie die Eigenschaft von einer URI an, anstatt Speicherströme zu verwenden." Quelle:„Leistungstipps für Windows Store-Apps mit XAML“

Um das Leistungsproblem zu lösen, kann das Repository-Muster verwendet werden, um eine Caching-Ebene bereitzustellen.Die Zwischenspeicherung kann im Speicher erfolgen, was zu Speicherproblemen führen kann, oder als Miniaturbilddateien, die sich in einem temporären Ordner befinden, der beim Beenden der App gelöscht werden kann.

Sie können verwenden

ImageSourceConverter-Klasse

um zu bekommen, was du willst

    img1.Source = (ImageSource)new ImageSourceConverter().ConvertFromString("/Assets/check.png");
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top