IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Silverlight Discussion :

Mouse Over ListBox


Sujet :

Silverlight

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 12
    Par défaut Mouse Over ListBox
    Bonjour ,

    Je viens vers vous aujourd'hui car j'ai un petit soucis qui parait simple comme ça mais que je n'arrive pas a résoudre.

    J'ai une ListBox j'affiche dans celle-ci des images,je lui ai appliqué un template qui modifie l'animation faite lors d'un mouseover. Jusque là tout va bien ma listbox m'affiche bien les éléments voulu. Maintenant je voudrait pouvoir afficher un texte qui décrit un peu l'image lors du mouseover sur celle-ci. Bien entendu chaque image à un descriptif différent donc il faudrait que je puisse récupérer l'élément de la listBox qui à le mouseover.

    Ensuite je pense que le mieux serait de binder un label (ou richtextbox je sais plus exactement le nom bref...) qui pourrait récuperer la description de l'image survolé.

    Mais ce n'est pas le plus important si déjà je peux récupérer l'élément courant dans le code behind pour affecter sa description à un label ça serait parfait.

    Merci d'avance pour votre

  2. #2
    Membre Expert
    Avatar de Samuel Blanchard
    Homme Profil pro
    Expert .NET
    Inscrit en
    Février 2010
    Messages
    1 504
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France

    Informations professionnelles :
    Activité : Expert .NET

    Informations forums :
    Inscription : Février 2010
    Messages : 1 504
    Par défaut
    Bonjour,

    Mais ce n'est pas le plus important si déjà je peux récupérer l'élément courant dans le code behind pour affecter sa description à un label ça serait parfait.
    Je ne pense pas que cela soit la meilleur idée. Il vaut mieux privilégier le Binding qui est plus simple à mettre en oeuvre en XAML.
    Tu peux, par exemple, créer un textblock contenant ta description (Binder) mais celui-ci est invisible tant que l'animation de l'état MouseOver n'est pas déclenchée.

    Sinon tu peux peut être aussi customiser un ToolTip.
    C'est sans doute le plus simple.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    <Image Source="{Binding MonImage}">
        <ToolTipService.ToolTip> 
            <ToolTip>
                <TextBlock Text="{Binding MaDescription}"></TextBlock>
            </ToolTip>
        </ToolTipService.ToolTip>
    </Image>

  3. #3
    Expert confirmé
    Avatar de Skyounet
    Homme Profil pro
    Software Engineer
    Inscrit en
    Mars 2005
    Messages
    6 380
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Software Engineer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 6 380
    Par défaut
    Le Tooltip est sans doute la méthode la plus facile à mettre en place.

    Sinon tu t'abonnes au MouseEnter de ta ListBox et si le e.OriginalSource == Grid (le template d'un ListBoxItem est composé d'un Grid) alors tu as ton ListBoxItem.

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 12
    Par défaut
    Bonjour ,

    Tout d'abord merci de ta réponse qui est tout a fait viable, j'y avait déjà pensé mais malheureusement un tooltip n'est pas suffisamment riche. Je serais plutôt preneur de ta 1 ère solution à savoir un textblock dans le stackpanel de ma listbox qui serait bind sur la description et qui apparaitrait lors du mouse over.

    J'ai fait toute les étapes nécessaire (binding placement retouche du style etc...) si je met la propriété Visibility à true cela me donne exactement ce que je veux or maintenant je ne sais pas comment faire pour l'afficher lors du mouseover.

    J'ai pensé à un binding entre control, je sais le faire pour binder 2 propriété d'élément entre elles mais pas pour binder un événement à une propriété. Il faudrait que lorsque l'évenement MouseOver est déclanché la propriete visiblility passe à Visible.

    Si tu as un pointeur ou autre je suis preneur (j'ai commencé à chercher ce que je pouvais trouver sur le sujet mais rien de bien concluant pour le moment)

  5. #5
    Membre Expert
    Avatar de Samuel Blanchard
    Homme Profil pro
    Expert .NET
    Inscrit en
    Février 2010
    Messages
    1 504
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France

    Informations professionnelles :
    Activité : Expert .NET

    Informations forums :
    Inscription : Février 2010
    Messages : 1 504
    Par défaut
    Regarde du coté des VisualStates (dont MouseOver) de ItemContainerStyle.
    Avec Blend c'est assez simple à modifier.

  6. #6
    Expert confirmé
    Avatar de Skyounet
    Homme Profil pro
    Software Engineer
    Inscrit en
    Mars 2005
    Messages
    6 380
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Software Engineer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 6 380
    Par défaut
    Citation Envoyé par UrdaUrda Voir le message
    J'ai fait toute les étapes nécessaire (binding placement retouche du style etc...) si je met la propriété Visibility à true cela me donne exactement ce que je veux or maintenant je ne sais pas comment faire pour l'afficher lors du mouseover.
    Ben fais le dans le VisualStateManager dans le state MouseOver !

    Pour le Tooltip tu peux mettre tout ce que tu veux dedans, tu n'es pas limité à du texte hein. Tu peux mettre une image, un RichText, bref ce que tu veux.

  7. #7
    Membre Expert
    Avatar de Samuel Blanchard
    Homme Profil pro
    Expert .NET
    Inscrit en
    Février 2010
    Messages
    1 504
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France

    Informations professionnelles :
    Activité : Expert .NET

    Informations forums :
    Inscription : Février 2010
    Messages : 1 504
    Par défaut
    pour changer la propriété Visibility dans une animation c'est comme ça (cela te servira surement) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    <Storyboard>
    	<ObjectAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="contentPresenter" Storyboard.TargetProperty="(UIElement.Visibility)">
    		<DiscreteObjectKeyFrame KeyTime="00:00:00.5000000">
    			<DiscreteObjectKeyFrame.Value>
    				<Visibility>Collapsed</Visibility>
    			</DiscreteObjectKeyFrame.Value>
    		</DiscreteObjectKeyFrame>
    	</ObjectAnimationUsingKeyFrames>
    </Storyboard>

  8. #8
    Membre Expert
    Avatar de Samuel Blanchard
    Homme Profil pro
    Expert .NET
    Inscrit en
    Février 2010
    Messages
    1 504
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France

    Informations professionnelles :
    Activité : Expert .NET

    Informations forums :
    Inscription : Février 2010
    Messages : 1 504
    Par défaut
    On fait de la Stéréo avec Sky, le son est meilleur comme ça

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 12
    Par défaut
    Bonjour ,

    Je viens de voir vos réponses , j'ai effectivement trouvé comment faire pour modifier les propriétés avec les VisualStates En revanche j'ai (encore) un dernier petit problème.

    Je peux modifier l'état d'un control, mais dans mon exemple j'ai une listBox avec un datatemplate (une image qui s'affiche et un textblock qui est collapsed) le problème c'est que je ne peux pas accéder au textblock de mon datatemplate.

    je vous met le code que j'ai pour mieux visualiser la chose.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
                <ListBox x:Name="ListV" ItemsSource="{Binding}" Width="800" HorizontalAlignment="Left" BorderBrush="White" Style="{StaticResource ListBoxStyle1}">
     
                    <ListBox.ItemsPanel>
                        <ItemsPanelTemplate>
                            <StackPanel Orientation="Horizontal"/>
                        </ItemsPanelTemplate>
                    </ListBox.ItemsPanel>
     
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <StackPanel>
                                <TextBlock x:Name="TextDesc" Visibility="Collapsed" Text="{Binding description}" />
                                <Image x:Name="ImgVoit" Source="{Binding url}" MouseEnter="Image_MouseEnter"/>
                            </StackPanel>
                        </DataTemplate>
                        </ListBox.ItemTemplate>                 
                    </ListBox>
    Je voudrait modifier juste la visibility de TextDesc mais si je fait ça lors du mouseover l'application plante en me disant qu'elle ne peut pas accéder à TextDesc.

  10. #10
    Membre Expert
    Avatar de Samuel Blanchard
    Homme Profil pro
    Expert .NET
    Inscrit en
    Février 2010
    Messages
    1 504
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France

    Informations professionnelles :
    Activité : Expert .NET

    Informations forums :
    Inscription : Février 2010
    Messages : 1 504
    Par défaut
    Oui, effectivement il n'est pas facile de mélanger ItemContainerStyle et DataTemplate.

    En revanche tu dois pouvoir rajouter facilement dans le DataTemplate un Border par exemple qui récupère l'evenement MouseEnter :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    <ListBox x:Name="ListBox">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <!-- Le Border est chargé de récupérer le MouseEnter -->
                <!-- (mais elle doit contenir un fond)-->
                <Border Height="50" Width="100" Background="Red" MouseEnter="Border_MouseEnter">
                    <Grid>
                        <!-- Mon template -->
                    </Grid>
                </Border>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
    puis dans l'evenement on fait ce que l'on veux.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    private void Border_MouseEnter(object sender, MouseEventArgs e)
    {
     
    }

  11. #11
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 12
    Par défaut
    Bonjour,

    J'ai essayer de faire avec un border comme tu me l'a dit, ça marche (tout comme avec un écouteur sur l'image) mais la problématique reste là même je n'arrive pas a accéder aux propriétés de mon textblock même dans le code behind.

    J'ai bien accées à ma listBox et à ces propriétés mais pas à celles des controls de son dataTemplate.

  12. #12
    Expert confirmé
    Avatar de Skyounet
    Homme Profil pro
    Software Engineer
    Inscrit en
    Mars 2005
    Messages
    6 380
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Software Engineer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 6 380
    Par défaut
    Citation Envoyé par UrdaUrda Voir le message
    Bonjour,

    J'ai essayer de faire avec un border comme tu me l'a dit, ça marche (tout comme avec un écouteur sur l'image) mais la problématique reste là même je n'arrive pas a accéder aux propriétés de mon textblock même dans le code behind.

    J'ai bien accées à ma listBox et à ces propriétés mais pas à celles des controls de son dataTemplate.
    Ben une fois que tu as ton Border tu peux prendre ses enfants (dont ton TextBlock).

    Essaye une méthode d'extension du type GetChildrenOfType

    Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public static IEnumerable<T> GetChildrenOfType<T>(this UIElement element)
        where T : UIElement
    {
        int count = VisualTreeHelper.GetChildrenCount(element);
        for (int i = 0; i < count; i++)
        {
            FrameworkElement child = (FrameworkElement)VisualTreeHelper.GetChild(element, i);
            if (typeof(T).IsAssignableFrom(child.GetType()))
                yield return child as T;
     
            foreach (var frameworkElement in GetChildrenOfType<T>(child))
                yield return frameworkElement;
        }
    }

    Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    private void Border_MouseEnter(object sender, MouseEventArgs e)
    {
        Border border = sender as Border;
        border.GetChildrenOfType<TextBlock>().FirstOfDefault().Text = "mon textblock";
    }

  13. #13
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 12
    Par défaut
    Merci pour votre aide ça tourne nickel

    J'aurais eu du mal a penser aux méthode d'extension pour avoir accès aux child c'est quand même super utile cette méthode.

    J'en ai d'ailleurs trouvé une autre (2 en fait) qui permet de retourner également une List de control d'un même type. Si jamais ça peut etre utile à quelqu'un.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
        public static List<T> GetChildObjects<T>(this DependencyObject obj, string name)
        {
            var retVal = new List<T>();
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
            {
                object c = VisualTreeHelper.GetChild(obj, i);
                if (c.GetType().FullName == typeof(T).FullName && (String.IsNullOrEmpty(name) || ((FrameworkElement)c).Name == name))
                {
                    retVal.Add((T)c);
                }
                var gc = ((DependencyObject)c).GetChildObjects<T>(name);
                if (gc != null)
                    retVal.AddRange(gc);
            }
     
            return retVal;
        }
     
        public static T GetChildObject<T>(this DependencyObject obj, string name) where T : DependencyObject
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
            {
                object c = VisualTreeHelper.GetChild(obj, i);
                if (c.GetType().FullName == typeof(T).FullName && (String.IsNullOrEmpty(name) || ((FrameworkElement)c).Name == name))
                {
                    return (T)c;
                }
                object gc = ((DependencyObject)c).GetChildObject<T>(name);
                if (gc != null)
                    return (T)gc;
            }
     
            return null;
        }
    J'ai également pu récupérer le mouseover sur l'image de mon datatemplate grace au Parent du sender donc plus de border(voici le code behind pour etre plus clair)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
            private void ImageVoit_MouseEnter(object sender, MouseEventArgs e)
            {
                Image lstVoit = sender as Image;
                StackPanel gr = lstVoit.Parent as StackPanel;
                gr.GetChildObject<TextBlock>("TextDesc").Visibility = Visibility.Visible;
            }
     
            private void ImageVoit_MouseLeave(object sender, MouseEventArgs e)
            {
                Image lstVoit = sender as Image;
                StackPanel gr = lstVoit.Parent as StackPanel;
                gr.GetChildObject<TextBlock>("TextDesc").Visibility = Visibility.Collapsed;
            }

  14. #14
    Membre Expert
    Avatar de Samuel Blanchard
    Homme Profil pro
    Expert .NET
    Inscrit en
    Février 2010
    Messages
    1 504
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France

    Informations professionnelles :
    Activité : Expert .NET

    Informations forums :
    Inscription : Février 2010
    Messages : 1 504
    Par défaut
    Sinon tu as aussi cette solution orientée Binding.
    Comme le DataContext de chaque enfant porte la donnée Bindée du DataTemplate tu peux faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    private void Border_MouseEnter(object sender, MouseEventArgs e)
    {
       Border border = sender as Border;
       // on récupère l'objet bindé
       MaDataBindee = border.DataContext as MaDataBindee;
       // on change la visibilité de la description
       MaDataBindee.DescriptionVisibility = Visibility.Visible;
    }

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    <ListBox x:Name="ListBox">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <!-- Le Border est chargé de récupérer le MouseEnter -->
                <!-- (mais elle doit contenir un fond)-->
                <Border Height="50" Width="100" Background="Red" MouseEnter="Border_MouseEnter">
                    <Grid>
                        <!-- Mon template -->
                                <TextBlock x:Name="TextDesc" Visibility="{Binding DescriptionVisibility}" Text="{Binding description}" />
                                <Image x:Name="ImgVoit" Source="{Binding url}" MouseEnter="Image_MouseEnter"/>
     
                    </Grid>
                </Border>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Faire apparaitre du texte avec un mouse over
    Par zooffy dans le forum Général JavaScript
    Réponses: 6
    Dernier message: 06/04/2008, 19h56
  2. [Traitement d'image] Galerie photo en mouse over
    Par heteroclite dans le forum Webdesign & Ergonomie
    Réponses: 3
    Dernier message: 19/03/2008, 17h31
  3. Réponses: 1
    Dernier message: 02/02/2008, 08h39
  4. Les images clignotes lors du Mouse over
    Par The Bat ! dans le forum C++Builder
    Réponses: 4
    Dernier message: 30/05/2005, 10h37
  5. Equivalent on mouse over en CSS
    Par pmithrandir dans le forum Mise en page CSS
    Réponses: 9
    Dernier message: 25/04/2005, 14h10

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo