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

Windows Presentation Foundation Discussion :

Binding sur les SelectedItems d'une ListBox ne fonctionne pas entièrement


Sujet :

Windows Presentation Foundation

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    284
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 284
    Points : 79
    Points
    79
    Par défaut Binding sur les SelectedItems d'une ListBox ne fonctionne pas entièrement
    Bonjour,
    Petit difficulté quand j'ai voulu me Binder sur les SelectedItems d'une ListBox.
    J'utiliser une classe mais impossible de la refaire marcher.
    Du coup j'ai décidé de m'y pencher dessus, l'avantage c'est que ça me fait découvrir de nouvelles choses.

    Mais je rencontre un problème.
    Voici la petite classe sans prétention que j'ai faite:
    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
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
     
    public static class ListBoxSelectedItems
    {
    	public static void SetSelectedItems(ListBox listbox, IList list){listbox.SetValue(SelectedItemsProperty,list);}
    	public static IList GetSelectedItems(ListBox listbox){return listbox.GetValue(SelectedItemsProperty) as IList;}
    	public static DependencyProperty SelectedItemsProperty = DependencyProperty.RegisterAttached("SelectedItems", typeof(IList), typeof(ListBoxSelectedItems), new PropertyMetadata(null, new PropertyChangedCallback(SelectedItemsProperty_Changed)));
     
    	private static void SelectedItemsProperty_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
    	{
    		if (!(d is ListBox) || !(e.NewValue is IList)) return;
     
    		((ListBox)d).SelectedItems.Clear();
    		foreach (var oneValue in ((IList)e.NewValue))
    			((ListBox) d).SelectedItems.Add(oneValue);
     
    		((ListBox)d).SelectionChanged += ListBox_SelectionChanged;
     
    	}
     
    	private static void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
    	{
    		if (!(sender is ListBox)) return;
    		var a = ((ListBox) sender).SelectedItems;
    	}
    }

    Je l'utilise de la façon suivante:
    Code xml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    <ListBox SelectionMode="Extended" DisplayMemberPath="Name" ItemsSource="{Binding Path=FullListValue, Mode=OneWay}" bh:ListBoxSelectedItems.SelectedItems="{Binding Path=ListValue, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}, Mode=TwoWay}" />

    Résultat:
    - Quand ListValue est rempli, j'ai bien les éléments qui se selectionnent dans ma ListBox ==> OK
    - Quand je modifie les éléments de la ListBox (en cliquant dessus), je rentre bien dans ListBox_SelectionChanged mais si je regarde la valeur de ListValue, elle ne change pas. ==> Pas OK

    Je pense qu'il me manque quelque chose dans ListBox_SelectionChanged mais je en vois pas quoi. Ou peut être que ça vient du Getter
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    public static IList GetSelectedItems(ListBox listbox){return listbox.GetValue(SelectedItemsProperty) as IList;}

    Quelqu'un pourrait il me donner quelques indications svp?
    Merci

  2. #2
    Invité
    Invité(e)
    Par défaut
    Salut,

    Je pense qu'il y a quelque chose qui manque dans ton gestionnaire
    Il faut ajouter que ça ressemble à ça mais j'ai pas testé :
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    private static void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
    	{
    		if (!(sender is ListBox)) return;
    		var a = ((ListBox) sender).SelectedItems;
                    SetSelectedItems(sender as ListBox, a)
    	}

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    284
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 284
    Points : 79
    Points
    79
    Par défaut
    Je viens d'essayer!
    Dès que je change la sélection, j'ai la valeur qui prend null.

    Je me demande si le problème ne vient pas plutôt de GetSelectedItems

    PS : Quoi que non, ça devrait venir de ce que tu dis. Je ne vois vraiment pas ce qui manque.

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    284
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 284
    Points : 79
    Points
    79
    Par défaut
    Voici un peu plus de détails sur mon code et mes test.
    J'ai tout mis dans le même fichier pour simplifier.

    Code xml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    <Window x:Class="Binding.ListBox.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:ListBox="clr-namespace:Binding.ListBox">
     
        <StackPanel>
            <ListBox ItemsSource="{Binding Path=ListUserFull, Mode=OneWay}" DisplayMemberPath="Lastname" ListBox:ListBoxSelectedItems.SelectedItems="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}}, Path=TheGroup.Users, Mode=TwoWay}" SelectionMode="Extended"/>
            <Button Content="Test" Click="Button_Click" />
        </StackPanel>
    </Window>


    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
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
     
    namespace Binding.ListBox
    {
        //GUI
        public partial class MainWindow : Window
        {
            public Group TheGroup { get; set; }
            public struct StructContext
            {
                public List<User> ListUserFull { get; set; }
            }
     
            public MainWindow()
            {
                InitializeComponent();
                var context = new StructContext() { ListUserFull = new Business().UserGetAll() };
     
                TheGroup = new Business().GetOneGroup();
                TheGroup.Users = TheGroup.Users.Select(oneUser => context.ListUserFull.FirstOrDefault(u => u.Id == oneUser.Id)).ToList();
                DataContext = context;
            }
     
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                if(TheGroup!=null && TheGroup.Users!=null)
                    Console.WriteLine("Il y a "+TheGroup.Users.Count+" utilisateurs selectionnés");
                else
                    Console.WriteLine("Il n'y a aucun utilisateur selectionné");
            }
        }
     
        //BLL
        public class Business
        {
            public List<User> UserGetAll()
            {
                return new List<User>{
                               new User(1, "DUPOND", "Martin"),
                               new User(2, "DURAND", "François"),
                               new User(3, "MACHIN", "Marc"),
                               new User(4, "GILLES", "Franck")
                           };
            }
     
            public Group GetOneGroup()
            {
                return new Group{
                               Users = new List<User>{
                                         new User(1, "DUPOND", "Martin"),
                                         new User(2, "DURAND", "François")
                                     }
                           };
            }
        }
     
        //ENTITY
        public class Group
        {
            public List<User> Users { get; set; }
        }
     
        public class User
        {
            public User(long id, string lastname, string firstname)
            {
                Id = id;
                Lastname = lastname;
                Firstname = firstname;
            }
     
            public long Id { get; set; }
            public string Lastname { get; set; }
            public string Firstname { get; set; }
        }
     
        //BEHAVIOR
        public static class ListBoxSelectedItems
        {
            public static void SetSelectedItems(System.Windows.Controls.ListBox listbox, IList list) { listbox.SetValue(SelectedItemsProperty, list); }
            public static IList GetSelectedItems(System.Windows.Controls.ListBox listbox) { return listbox.GetValue(SelectedItemsProperty) as IList; }
            public static DependencyProperty SelectedItemsProperty = DependencyProperty.RegisterAttached("SelectedItems", typeof(IList), typeof(ListBoxSelectedItems), new PropertyMetadata(null, new PropertyChangedCallback(SelectedItemsProperty_Changed)));
     
            private static void SelectedItemsProperty_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
            {
                if (!(d is System.Windows.Controls.ListBox) || !(e.NewValue is IList)) return;
     
                ((System.Windows.Controls.ListBox)d).SelectedItems.Clear();
                foreach (var oneValue in ((IList)e.NewValue))
                    ((System.Windows.Controls.ListBox)d).SelectedItems.Add(oneValue);
     
                ((System.Windows.Controls.ListBox)d).SelectionChanged += ListBox_SelectionChanged;
            }
     
            private static void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
            {
                if (!(sender is System.Windows.Controls.ListBox)) return;
            }
        }
    }

    A ce niveau là:
    1) Lorsque je charge ma page j'ai bien les deux premiers items de selectionnés
    2) Lorsque je clique sur le bouton, il y a bien deux items.
    3) Si je sélectionne 3 items et que je clique sur le bouton il ne connait que les deux premiers.


    Je modifie donc la méthode SelectionChanged
    Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    private static void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
            {
                if (!(sender is System.Windows.Controls.ListBox)) return;
                var theListbox = sender as System.Windows.Controls.ListBox;
                SetSelectedItems(theListbox, theListbox.SelectedItems);
            }
    A ce niveau là:
    1) IDEM
    2) IDEM
    3) Si je sélectionne 3 items et que je clique sur le bouton, j'obtiens la valeur null.


    Je ne comprend pas pourquoi. Quelqu’un a t'il une idée?

  5. #5
    Invité
    Invité(e)
    Par défaut
    Re-salut,

    Je ne sais pas pourquoi ça ne marche pas, mais j'ai essayé le code fourni dans cette discussion de ce forum et tout marchait. Il suffit de l'adapter pour que ça marche en WPF.

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    284
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 284
    Points : 79
    Points
    79
    Par défaut
    Je vais me repencher sur le code que tu m'as donné, mais je ne comprends pas pourquoi le miens ne fonctionne pas! Mais merci pour ton aide malgré tout

Discussions similaires

  1. [Windows Phone 8] Gestion de la gestuelle sur les éléments d'une ListBox
    Par Eurkainis dans le forum Windows Phone
    Réponses: 2
    Dernier message: 19/06/2014, 09h51
  2. [Flex4] binding sur les attributs d'une classe
    Par j-jorge dans le forum Flex
    Réponses: 1
    Dernier message: 09/09/2010, 13h26
  3. Question sur les items d'une ListBox
    Par arnofly dans le forum Windows Forms
    Réponses: 6
    Dernier message: 15/06/2009, 19h19
  4. Réponses: 9
    Dernier message: 18/02/2008, 11h00
  5. Réponses: 13
    Dernier message: 24/08/2006, 13h05

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