Question

J'essaie de lier une liste d'objets personnalisés à une image WPF comme ceci :

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

Mais ça ne marche pas.Voici l'erreur que j'obtiens :

"La propriété 'UriSource' ou la propriété 'StreamSource' doit être définie."

Qu'est-ce que je rate?

Était-ce utile?

La solution

WPF dispose de convertisseurs intégrés pour certains types.Si vous liez l'image Source propriété à un string ou Uri valeur, sous le capot, WPF utilisera un Convertisseur de source d'image pour convertir la valeur en un ImageSource.

Donc

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

fonctionnerait si la propriété ImageSource était une représentation sous forme de chaîne d'un URI valide pour une image.

Vous pouvez bien sûr lancer votre propre convertisseur de liaison :

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

et utilisez-le comme ceci :

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

Autres conseils

Cet article par Atul Gupta propose un exemple de code qui couvre plusieurs scénarios :

  1. Liaison d’image de ressource régulière à la propriété Source dans XAML
  2. Image de ressource de liaison, mais à partir du code derrière
  3. Liaison de l'image de ressource dans le code derrière à l'aide de Application.GetResourceStream
  4. Chargement de l'image à partir du chemin du fichier via le flux de mémoire (la même chose s'applique lors du chargement des données d'image de blog à partir de la base de données)
  5. Chargement de l'image à partir du chemin du fichier, mais en utilisant la liaison à un chemin de fichier
  6. Liaison des données d'image à un contrôle utilisateur qui dispose en interne d'un contrôle d'image via une propriété de dépendance
  7. Identique au point 5, mais en veillant également à ce que le fichier ne soit pas verrouillé sur le disque dur

Vous pouvez également simplement définir l'attribut Source plutôt que d'utiliser les éléments enfants.Pour ce faire, votre classe doit renvoyer l'image sous forme d'image Bitmap.Voici un exemple d'une façon dont je l'ai fait

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

Et la propriété de classe est simplement celle-ci

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

Je suppose que cela demande peut-être un peu plus de travail que le convertisseur de valeur, mais c'est une autre option.

Vous devez avoir une implémentation de IValueConvertisseur interface qui convertit l’uri en image.Votre implémentation Convert de IValueConverter ressemblera à ceci :

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

return image;

Ensuite, vous devrez utiliser le convertisseur dans votre liaison :

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

Le problème avec la réponse choisie ici est que lors de la navigation d'avant en arrière, le convertisseur se déclenchera à chaque fois que la page est affichée.

Cela entraîne la création continue de nouveaux descripteurs de fichiers et bloque toute tentative de suppression du fichier car il est toujours en cours d'utilisation.Cela peut être vérifié à l'aide de Process Explorer.

Si le fichier image risque d'être supprimé à un moment donné, un convertisseur tel que celui-ci peut être utilisé :utiliser XAML pour se lier à un System.Drawing.Image dans un contrôle System.Windows.Image

L'inconvénient de cette méthode de flux mémoire est que la ou les images sont chargées et décodées à chaque fois et qu'aucune mise en cache ne peut avoir lieu :"Pour éviter que les images ne soient décodées plus d'une fois, affectez la propriété Image.source à partir d'un URI plutôt que d'utiliser des flux de mémoire" Source:"Conseils de performances pour les applications du Windows Store utilisant XAML"

Pour résoudre le problème de performances, le modèle de référentiel peut être utilisé pour fournir une couche de mise en cache.La mise en cache peut avoir lieu en mémoire, ce qui peut entraîner des problèmes de mémoire, ou sous forme de fichiers miniatures résidant dans un dossier temporaire pouvant être effacés à la fermeture de l'application.

vous pouvez utiliser

Classe ImageSourceConverter

pour obtenir ce que tu veux

    img1.Source = (ImageSource)new ImageSourceConverter().ConvertFromString("/Assets/check.png");
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top