web-dev-qa-db-fra.com

Liaison d'une image dans WPF MVVM

J'ai des problèmes pour lier Image à mon modèle de vue. Je me suis finalement débarrassé de XamlParseException, mais l'image ne s'affiche pas. J'ai même codé l'image dans le ViewModel. Est-ce que quelqu'un peut voir ce que je fais mal? 

Vue:

<Image HorizontalAlignment="Left" Margin="0,0,0,0" Name="image1" Stretch="Fill" VerticalAlignment="Bottom" Grid.Row="8" Width="200"  Grid.ColumnSpan="2" >
<Image.Source>
    <BitmapImage DecodePixelWidth="200" UriSource="{Binding Path=DisplayedImage, Mode=TwoWay}" />
</Image.Source>

ViewModel:

 string _DisplayedImagePath = @"C:\Users\Public\Pictures\Sample Pictures\Chrysanthemum.jpg";//string.Empty;
    int _DisplayedImageIndex;
    BitmapImage _DisplayedImage = null;
    public BitmapImage DisplayedImage
    {
        get
        {
            _DisplayedImage = new BitmapImage();
            if (!string.IsNullOrEmpty(_DisplayedImagePath))
            {
                _Rail1DisplayedImage.BeginInit();
                _Rail1DisplayedImage.CacheOption = BitmapCacheOption.OnLoad;
                _Rail1DisplayedImage.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
                _Rail1DisplayedImage.UriSource = new Uri(_DisplayedImagePath);
                _Rail1DisplayedImage.DecodePixelWidth = 200;
                _Rail1DisplayedImage.EndInit();
            }
            return _Rail1DisplayedImage;
        }
        set
        {
            _Rail1DisplayedImage = value;
            OnPropertyChanged("DisplayedImage");
        }
    }
34
kurgaan

Afficher une Image dans WPF est beaucoup plus facile que cela. Essaye ça:

<Image Source="{Binding DisplayedImagePath}" HorizontalAlignment="Left" 
    Margin="0,0,0,0" Name="image1" Stretch="Fill" VerticalAlignment="Bottom" 
    Grid.Row="8" Width="200"  Grid.ColumnSpan="2" />

Et la propriété peut simplement être une string:

public string DisplayedImage 
{
    get { return @"C:\Users\Public\Pictures\Sample Pictures\Chrysanthemum.jpg"; }
}

Bien que vous deviez vraiment ajouter vos images à un dossier nommé Images à la racine de votre projet et définir leur Action de construction sur Resource dans la fenêtre Propriétés de Visual Studio ... vous pouvez ensuite accédez-y en utilisant ce format:

public string DisplayedImage 
{
    get { return "/AssemblyName;component/Images/ImageName.jpg"; }
}

MISE À JOUR >>>

Dernier conseil ... Si vous rencontrez un problème avec un contrôle qui ne fonctionne pas comme prévu, tapez simplement "WPF", le nom de ce contrôle, puis le mot "classe" dans un moteur de recherche. Dans ce cas, vous auriez tapé 'WPF Image Class'. Le premier résultat sera toujours MSDN et si vous cliquez sur le lien, vous saurez tout sur ce contrôle et la plupart des pages contiennent également des exemples de code.


MISE À JOUR 2 >>>

Si vous avez suivi les exemples du lien vers MSDN et que cela ne fonctionne pas, votre problème est alors not le contrôle Image. En utilisant la propriété string que j'ai suggérée, essayez ceci:

<StackPanel>
    <Image Source="{Binding DisplayedImagePath}" />
    <TextBlock Text="{Binding DisplayedImagePath}" />
</StackPanel>

Si vous ne pouvez pas voir le chemin du fichier dans TextBlock, vous n'avez probablement pas défini votre DataContext sur l'instance de votre modèle de vue. Si vous pouvez voir le texte, le problème vient du chemin de votre fichier.


MISE À JOUR 3 >>>

Dans .NET 4, les valeurs ci-dessus Image.Source fonctionneraient. Cependant, Microsoft a apporté des modifications horribles dans .NET 4.5 qui ont cassé beaucoup de choses différentes et donc dans .NET 4.5, vous auriez besoin d'utiliser le chemin complet pack comme ceci:

<Image Source="pack://application:,,,/AssemblyName;component/Images/image_to_use.png">

Pour plus d'informations sur les URI de pack, veuillez consulter la page URI de pack dans WPF page sur Microsoft Docs.

72
Sheridan

@ Sheridan thx .. si j'essaie votre exemple avec "DisplayedImagePath" des deux côtés, cela fonctionne avec le chemin absolu que vous montrez. 

En ce qui concerne les chemins relatifs, c’est ainsi que je connecte toujours les chemins relatifs, j’inclue d’abord le sous-répertoire (!) Et le fichier image dans mon projet .. puis j'utilise le caractère ~ pour désigner le chemin bin.

    public string DisplayedImagePath
    {
        get { return @"~\..\images\osc.png"; }
    }

Cela a été testé, voir ci-dessous mon Solution Explorer dans VS2015 ..

 example of image binding in VS2015 )

Remarque: si vous souhaitez un événement Click, utilisez la balise Button autour de l'image ,

<Button Click="image_Click" Width="128" Height="128"  Grid.Row="2" VerticalAlignment="Top" HorizontalAlignment="Left">
  <Image x:Name="image" Source="{Binding DisplayedImagePath}" Margin="0,0,0,0" />
</Button>

0
Goodies