Image UriSource et Data Binding

j'essaie de lier une liste d'objets personnalisés à une Image WPF comme celle-ci:

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

mais ça ne marche pas. C'est l'erreur que j'obtiens:

"Propriété " UriSource' ou bien 'StreamSource" doit être réglé."

Qu'est-ce que je rate?

59
demandé sur H.B. 2008-08-21 21:21:01

6 réponses

WPF a des convertisseurs intégrés pour certains types. Si vous liez la propriété Source de L'Image à une valeur string ou Uri , sous le capot WPF utilisera un ImageSourceConverter pour convertir la valeur en ImageSource .

Donc

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

fonctionnerait si la propriété ImageSource était une représentation string d'un URI valide d'une image.

vous pouvez bien sûr rouler 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 l'utiliser comme ceci:

<Image Source="{Binding ImageSource, Converter={StaticResource ImageConverter}}"/>
76
répondu Brian Leahy 2017-11-09 10:02:00

cet article par Atul Gupta a un code échantillon qui couvre plusieurs scénarios:

  1. Régulier image de ressource de liaison à la Source de la propriété dans le code XAML
  2. la Liaison des ressources de l'image, mais à partir de code derrière
  3. lier l'image de ressource en code derrière en utilisant L'Application.GetResourceStream
  4. chargement de l'image à partir du chemin du fichier via le flux de mémoire (il en va de même pour le chargement de blog données d'image à partir de la base de données)
  5. chargement de l'image à partir du chemin du fichier, mais en utilisant la liaison à une propriété du chemin du fichier
  6. lier des données d'image à un contrôle d'utilisateur qui a en interne le contrôle d'image via une propriété de dépendance
  7. identique au point 5, mais aussi en s'assurant que le fichier n'est pas verrouillé sur le disque dur
23
répondu Drew Noakes 2009-05-14 10:18:33

vous pouvez aussi simplement définir l'attribut Source plutôt que d'utiliser les éléments enfants. Pour ce faire, votre classe doit retourner l'image en 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 classe de la propriété est tout simplement ce

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 qu'il peut être un peu plus de travail que le convertisseur de valeur, mais c'est une autre option.

19
répondu palehorse 2008-08-21 17:54:38

vous devez avoir une implémentation de IValueConverter interface qui convertit l'uri en une image. Votre implémentation convertie de IValueConverter ressemblera à quelque chose comme ceci:

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

return image;

, Alors vous devrez utiliser le convertisseur dans votre liaison:

<Image>
    <Image.Source>
        <BitmapImage UriSource="{Binding Path=ImagePath, Converter=...}" />
    </Image.Source>
</Image>
9
répondu Dale Ragan 2008-08-21 17:35:54

le problème avec la réponse qui a été choisie ici est que lors de la navigation de va-et-vient, le convertisseur sera déclenché chaque fois que la page est affichée.

cela crée de nouvelles poignées de fichier en continu et bloque toute tentative de supprimer le fichier parce qu'il est toujours utilisé. Ceci peut être vérifié en utilisant Process Explorer.

si le fichier image peut être supprimé à un moment donné, un convertisseur tel que celui-ci peut être utilisé: utilisant XAML pour se lier à un système.Dessin.Image dans un Système.Windows.Contrôle d'Image

l'inconvénient de cette méthode de flux de mémoire est que 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, assignez l'Image.Propriété Source d'un Uri plutôt que d'utiliser des flux de mémoire" Source: "conseils de Performance pour les applications Windows Store utilisant XAML "

pour résoudre le problème de performance, le motif du dépôt peut être utilisé pour fournir une couche de cache. La mise en cache peut avoir lieu en mémoire, ce qui peut causer des problèmes de mémoire, ou sous forme de vignettes de fichiers qui résident dans un dossier temporaire qui peut être effacé lorsque l'application sort.

6
répondu Luis Cantero 2017-05-23 12:26:19

vous pouvez utiliser

ImageSourceConverter class

pour obtenir ce que vous voulez

    img1.Source = (ImageSource)new ImageSourceConverter().ConvertFromString("/Assets/check.png");
4
répondu Karthik Krishna Baiju 2013-10-20 18:00:02