Domanda

Sto cercando di associare un elenco di oggetti personalizzati a un'immagine WPF come questa:

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

Ma non funziona.Questo è l'errore che ricevo:

"È necessario impostare la proprietà 'UriSource' o la proprietà 'StreamSource'."

Cosa mi manca?

È stato utile?

Soluzione

WPF dispone di convertitori incorporati per determinati tipi.Se leghi i file Image's Source proprietà ad a string O Uri valore, sotto il cofano WPF utilizzerà un file ImageSourceConverter per convertire il valore in un ImageSource.

COSÌ

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

funzionerebbe se la proprietà ImageSource fosse una rappresentazione di stringa di un URI valido in un'immagine.

Ovviamente puoi creare il tuo convertitore di rilegatura:

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();
    }
}

e usarlo in questo modo:

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

Altri suggerimenti

Questo articolo di Atul Gupta contiene un codice di esempio che copre diversi scenari:

  1. Associazione regolare dell'immagine della risorsa alla proprietà Source in XAML
  2. Associazione dell'immagine della risorsa, ma dal codice dietro
  3. Associazione dell'immagine della risorsa nel code-behind utilizzando Application.GetResourceStream
  4. Caricamento dell'immagine dal percorso del file tramite flusso di memoria (lo stesso vale quando si caricano i dati dell'immagine del blog dal database)
  5. Caricamento dell'immagine dal percorso del file, ma utilizzando l'associazione a una proprietà del percorso del file
  6. Associazione dei dati dell'immagine a un controllo utente che dispone internamente del controllo dell'immagine tramite la proprietà di dipendenza
  7. Come al punto 5, ma assicurandosi anche che il file non venga bloccato sul disco rigido

Puoi anche semplicemente impostare l'attributo Source anziché utilizzare gli elementi figlio.Per fare ciò la tua classe deve restituire l'immagine come immagine bitmap.Ecco un esempio di un modo in cui l'ho fatto

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

E la proprietà della classe è semplicemente questa

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;
    }
}

Suppongo che potrebbe richiedere un po' più di lavoro rispetto al convertitore di valori, ma è un'altra opzione.

È necessario disporre di un'implementazione di IValueConverter interfaccia che converte l'URI in un'immagine.L'implementazione Convert di IValueConverter sarà simile a questa:

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

return image;

Quindi dovrai utilizzare il convertitore nella tua rilegatura:

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

Il problema con la risposta scelta qui è che durante la navigazione avanti e indietro, il convertitore si attiverà ogni volta che viene visualizzata la pagina.

Ciò provoca la creazione continua di nuovi handle di file e bloccherà qualsiasi tentativo di eliminare il file perché è ancora in uso.Questo può essere verificato utilizzando Process Explorer.

Se a un certo punto il file immagine viene eliminato, è possibile utilizzare un convertitore come questo:utilizzando XAML per associare un System.Drawing.Image a un controllo System.Windows.Image

Lo svantaggio di questo metodo del flusso di memoria è che le immagini vengono caricate e decodificate ogni volta e non è possibile eseguire la memorizzazione nella cache:"Per evitare che le immagini vengano decodificate più di una volta, assegnare l'immagine. Proprietà in base a un URI anziché usare flussi di memoria" Fonte:"Suggerimenti sulle prestazioni per le app di Windows Store che utilizzano XAML"

Per risolvere il problema delle prestazioni, è possibile utilizzare il modello del repository per fornire un livello di memorizzazione nella cache.La memorizzazione nella cache potrebbe avvenire in memoria, il che potrebbe causare problemi di memoria, o come file di miniature che risiedono in una cartella temporanea che può essere cancellata all'uscita dell'app.

Puoi usare

Classe ImageSourceConverter

per ottenere quello che vuoi

    img1.Source = (ImageSource)new ImageSourceConverter().ConvertFromString("/Assets/check.png");
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top