Binding textBlock et image dans une listBox [Résolu]

moi411 180 Messages postés samedi 22 novembre 2003Date d'inscription 25 juin 2017 Dernière intervention - 5 avril 2015 à 10:54 - Dernière réponse : moi411 180 Messages postés samedi 22 novembre 2003Date d'inscription 25 juin 2017 Dernière intervention
- 6 avril 2015 à 15:16
Bonjour,
J'ai une listbox dont chaque item est une "grid" composée d'une image et d'un label.

La listbox est rempli par binding sur une liste toute bête (List<> liste etc.)

Quand je sélectionne un item je voudrais afficher une image pour indiquer sur quel item je me trouve...

code pour le binding listBox - List<>:

<ListBox Height="Auto" HorizontalAlignment="Right" Margin="0,50,0,0" Name="listeListBox" VerticalAlignment="Stretch" Width="545" >            
            
<ListBox.ItemTemplate>
                <DataTemplate>
                    <Grid>
                        <Image HorizontalAlignment="Left" Margin="0" Width="60" />
                        <Label Content="{Binding Name}" HorizontalAlignment="Left" Margin="60,0,0,0" Tag="{Binding FullName}" />
                    </Grid>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>



code pour remplir la listBox (en précisant que je dois rajouter des items de temps à autre):

listeListBox.ItemsSource = null;
listeListBox.ItemsSource = liste; //ma fameuse liste générique!

J'ai essayé de mettre mon image via l'évènement SelectionChanged de la ListBox mais comment accéder au control "Image" du bon item?!?

J'espère avoir assez détaillé et que quelqu'un pourra m'aider!
A bientôt.
EDIT: Ajout de la coloration syntaxique.
Afficher la suite 

Votre réponse

6 réponses

Meilleure réponse
moi411 180 Messages postés samedi 22 novembre 2003Date d'inscription 25 juin 2017 Dernière intervention - Modifié par Whismeril le 6/04/2015 à 15:35
1
Merci
Donc comme dit plus haut, j'ai essayé et ça fonctionne!
Comme un peiti exemple vaut mieux qu'un long discour, j'ai fait une petite application qui explique ce que je voulais faire...


Le xaml d'abord

<Window x:Class="BindingTest.MainWindow"
        xmlns="[http://schemas.microsoft.com/winfx/2006/xaml/presentation]"
        xmlns:x="[http://schemas.microsoft.com/winfx/2006/xaml]"
        Title="MainWindow" Height="400" Width="320" Loaded="Window_Loaded">
    
    <Grid>
        
        <ListBox HorizontalAlignment="Stretch" Margin="0,50,0,0" Name="MaListBox" VerticalAlignment="Stretch" Grid.ColumnSpan="2" PreviewMouseDown="MaListBox_PreviewMouseDown" >
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Grid>
                        <Image Height="15" HorizontalAlignment="Left" Margin="0" Source="{Binding Img}" VerticalAlignment="Center" Width="50" />
                        <Label Content="{Binding NomItem}" HorizontalAlignment="Stretch" Margin="60,0,0,0" VerticalAlignment="Top" />
                    </Grid>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

        <Button Content="Item suivant" HorizontalAlignment="Center" Margin="0,20,120,0" Name="nextButton" VerticalAlignment="Top" Width="100" Height="20" Click="nextButton_Click"/>
        <Button Content="Item précédent" HorizontalAlignment="Center" Margin="120,20,0,0" Name="previousButton" VerticalAlignment="Top" Width="100" Height="20" Click="previousButton_Click"/>

    </Grid>
</Window>



Ensuite la classe:

using System.ComponentModel;

namespace BindingTest
{
    class TestPropertyChanged : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;   //Evènement qui va faire en sorte que les changements d'image seront pris en compte
        
        //Les propriétés
        public string NomItem { get; set; }

        private string _Img;
        public string Img
        {
            get
            {
                return _Img;
            }
            set
            {
                _Img = value;
                MyPropertyChanged("Img"); //la propriété de ma classe que le "binding" influencera
            }
        }

        //constructeur
        public TestPropertyChanged(string nItem, string itemSelection)
        {
            NomItem = nItem;
            _Img = itemSelection;
        }

        //méthode qui est applée en cas de changement de la propriété
        protected void MyPropertyChanged(string propertyName)
        {
            if (PropertyChanged == null)
            {
                return;
            }
            else
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}



Et enfin le corps du programme:

using System.Collections.Generic;
using System.Windows;
using System.Windows.Input;

namespace BindingTest
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        //chemin complet de l'image
        const string sourceImage = @"C:\Users\Thomas\Desktop\BindingTest\BindingTest\Images\fleche_droite.png";

        List<TestPropertyChanged> liste;    //la liste... rien à ajouter!
        int index;                          //numéro de l'item dans la liste


        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            index = 0;

            liste = new List<TestPropertyChanged>();
            liste.Add(new TestPropertyChanged("Item 01", sourceImage));     //La logique veut commencer à sélectionner les item par le début donc chemin de l'image symbolisant la selection!
            liste.Add(new TestPropertyChanged("Item 02", null));            //Ensuite, null (ce qui n'affichera pas l'image!!!).
            liste.Add(new TestPropertyChanged("Item 03", null));
            liste.Add(new TestPropertyChanged("Item 04", null));
            liste.Add(new TestPropertyChanged("Item 05", null));
            liste.Add(new TestPropertyChanged("Item 06", null));
            liste.Add(new TestPropertyChanged("Item 07", null));
            liste.Add(new TestPropertyChanged("Item 08", null));
            liste.Add(new TestPropertyChanged("Item 09", null));
            liste.Add(new TestPropertyChanged("Item 10", null));

            MaListBox.ItemsSource = liste;
        }


        private void nextButton_Click(object sender, RoutedEventArgs e)
        {
            liste[index].Img = null;                                            //on chage d'item, donc plus besoin d'afficher l'image
            index = (index < MaListBox.Items.Count - 1) ? index + 1 : 0;        //on incrémente l'indice servant à choisir les item dans la liste (si on arrive au bout de la liste, on revien au début)
            liste[index].Img = sourceImage;                                     //affichage de l'image à l'indice suivant
        }
        private void previousButton_Click(object sender, RoutedEventArgs e)
        {
            //même principe que pour "nextButton_Click"

            liste[index].Img = null;
            index = (index == 0) ? MaListBox.Items.Count - 1 : index - 1;      
            liste[index].Img = sourceImage;  
        }


        private void MaListBox_PreviewMouseDown(object sender, MouseButtonEventArgs e)
        {
            //Come je veux symboliser la sélection à ma manière, j'annule l'évènement natif de la listBox
            e.Handled = true;
        }        
    }
}


EDIT: Précision du langage dans la coloration syntaxique.

Merci moi411 1

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 102 internautes ce mois-ci

Commenter la réponse de moi411
Whismeril 12117 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 19 octobre 2018 Dernière intervention - 5 avril 2015 à 13:56
0
Merci
Bonjour, ce qu'il faut c'est que la classe qui remplit ta liste (que tu n'as pas montrée) ait une propriété qui permettra au template de charger la bonne image, cette propriété doit être de type BitmapImage et avoir au préalable été chargée de l'image correspondante à ton item.

            Uri uri = new Uri(@"C:\Users\Public\Pictures\Sample Pictures\Chrysanthemum.jpg");
            BitmapImage img = new BitmapImage(uri);//chargement de la propriété


et le template
        <Image  HorizontalAlignment="Left" Height="100" Margin="1381,164,0,0" VerticalAlignment="Top" Width="100" Source="{Binding MonImage}"/>

moi411 180 Messages postés samedi 22 novembre 2003Date d'inscription 25 juin 2017 Dernière intervention - 5 avril 2015 à 14:06
Re,
En fait je n'avais pas pensé que que l'astuce se trouverai dans la classe (je me suis surement bourré le crane et ai forcément zappé un détail!).

Toujours est-il qu'entre temps j'ai modifié ma classe et en suis arrivé pratiquement à la même chose que toi; ma variable est de type string et contient le chemin de l'image à afficher ou null (selon qu'il y ai ou non besoin d'afficher)!

J'ai pourtant encore une question, pour afficher la modification je suis obligé de recharger mon "ItemsSource"... Est-ce que je fais bien ou y a-t-il une façon de procéder moins "triche"?

Encore merci!
Whismeril 12117 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 19 octobre 2018 Dernière intervention > moi411 180 Messages postés samedi 22 novembre 2003Date d'inscription 25 juin 2017 Dernière intervention - 5 avril 2015 à 17:34
Il faut que ta classe implémente INotifyPropertyChanged, et bien sûr que les propriétés concernées alertent de leur changement. Le binding se mettra (normalement) à jour tout seul
moi411 180 Messages postés samedi 22 novembre 2003Date d'inscription 25 juin 2017 Dernière intervention - 5 avril 2015 à 22:21
D'accord, je vais essayer ça...
Je te remercie et joyeuse Pâques!
Commenter la réponse de Whismeril
moi411 180 Messages postés samedi 22 novembre 2003Date d'inscription 25 juin 2017 Dernière intervention - 5 avril 2015 à 13:56
0
Merci
Re-bonjour,
Et bien en fait j'ai trouvé...
C'est dans ma classe que ça se passe!

En gros j'utilise une variable par élément à "binder". En l'occurence j'ai rajouté une variable de type string dans ma classe qui correspond au chemin de l'image (contient null si pas pas besoin d'afficher et contient le chemin en question si besoin d'afficher!)...

Ensuite je jongle:

itemssource = null;
modification de la variable "source" (class.variable = chemin;) puis
itemssource = liste;

J'explique en vitesse mais je peux toujours détailler si besoin!
Et si il y a un autre moyen moins "triche", je suis preneur quand-même!

Voilà à bientôt!
--
Commenter la réponse de moi411

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.