locked
Comment ordonner une ObservableCollection pour une application Windows store ? RRS feed

  • Question

  • Bonjour,
     
    Comment ordonner une ObservableCollection pour une application Windows
    store ?
     
    Je cherche a comprendre comment on peut ordonner une
    ObservableCollection.
    J’ai vue que l’on pouvait utiliser un CollectionViewSource et qu’il y avait
    une propriété SortDescritption mais apparemment cette propriété n’existe pas
    dans mon cas (Application pour le Windows store)
     
    Comment faire alors ?
     
    J’ai bien vu un genre de réponse mais je ne la comprends pas.
     
     
    Ci-dessous mon exemple.
     

    J’ai repris cette exemple de la page http://msdn.microsoft.com/fr-fr/library/vstudio/ms748365.aspx

        public class PersonName
        {
            private string firstName;
            private string lastName;
    
            public PersonName(string first, string last)
            {
                this.firstName = first;
                this.lastName = last;
            }
    
            public string FirstName
            {
                get { return firstName; }
                set { firstName = value; }
            }
    
            public string LastName
            {
                get { return lastName; }
                set { lastName = value; }
            }
        }

        public class NameList : ObservableCollection<PersonName>
        {
            public NameList()
                : base()
            {
                Add(new PersonName("Willa", "Cather"));
                Add(new PersonName("Isak", "Dinesen"));
                Add(new PersonName("Victor", "Hugo"));
                Add(new PersonName("Jules", "Verne"));
            }
        }


    <Page
        x:Class="ExempleCollection.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:ExempleCollection"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        xmlns:c="using:ExempleCollection">
    
        <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
            <Grid.Resources>
                <c:NameList x:Key="NameListData" />
                <CollectionViewSource Source="{StaticResource NameListData}"
                                      x:Key="CollectionViewSourceKey">                
                </CollectionViewSource>
            </Grid.Resources>
            
            <ListBox Width="200" Height="400"
                     ItemsSource="{Binding Source={StaticResource CollectionViewSourceKey}}" >
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal">
                            <TextBlock Text="{Binding FirstName}"></TextBlock>
                            <TextBlock Text=" " />
                            <TextBlock Text="{Binding LastName}"></TextBlock>
                        </StackPanel>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
        </Grid>
    </Page>

    Et tout ça ça donne une bel écran avec mes personnes.

    Mais comment les mettre dans l'ordre alphabétique ?

    Merci.

     
    mardi 18 décembre 2012 09:17

Réponses

  • Tout d'abord, les données sont toujours fournies par le viewmodel (en fait par toute classe qui implémente INotifyPropertyChanged ou INotifyCollectionChanged).

    Pour le point 1, je dis que la classe NameList n'est pas nécessaire, il suffit de déclarer dans le viewmodel la liste de personnes avec le type ObservableCollection<PersonName>

    Pour le point 2, Le seul moyen qu'a la vue de modifier les données est d'ajouter un converter au binding (classe qui implémente IValueConverter). Quand j'ai besoin de formater des données qui ne sont utilisées que pour l'affichage, je définis des propriétés en lecture seule qui mettent en forme les données (voir l'exemple plus haut)

    il faut penser cependant à prévenir la vue que la propriété doit être rafraichie lorsque la liste privée a changée ses éléments:

    ListeNomsInterne.CollectionChanged += (s, e) => 
    {
        if (PropertyChanged != null) 
        {
            PropertyChanged(this, new PropertyChangedEventArgs("ListeTriee"));
        }
    }


    mardi 18 décembre 2012 23:24

Toutes les réponses

  • 2 choses:

    Ici hériter de ObservableCollection<T> n'a pas trop d'intérêt, car il n'y a pas de changement du comportement de la liste (pas de méthodes modifiées ni de propriétés), donc mieux vaut passer par une propriété de type ObservableCollection<PersonName> dans la classe reliée à la vue (le ViewModel)

    Puis, en gérant le contenu de la liste par le ViewModel, cette liste peut être maintenue privée dans le ViewModel, et ne publier qu'une propriété avec un simple get comme ceci en transformant la liste avec une requête linq:

    public IEnumerable<PersonName> ListeTriee 
    {
        get 
        {
            return ListePersonnes.OrderBy(p => p.Nom);
        }
    }


    • Proposé comme réponse Sylvain Platek mardi 18 décembre 2012 20:12
    mardi 18 décembre 2012 19:00
  • 1. Je ne comprends pas trop pour ce qui est du ObservableCollection<T> vs ObservableCollection<PersonName> car ma classe est déjà ObservableCollection<PersonName>

    public class NameList : ObservableCollection<PersonName>

    2. Ajouter une propriété private au ViewModele, pourquoi pas, d'ailleurs c'est ce que j'ai fini par faire. Mais il me semblai que la vue elle même possédait un mécanisme permettant de trier, sans requêter d'une façon particulière la source de données. Non ?

    mardi 18 décembre 2012 21:05
  • Tout d'abord, les données sont toujours fournies par le viewmodel (en fait par toute classe qui implémente INotifyPropertyChanged ou INotifyCollectionChanged).

    Pour le point 1, je dis que la classe NameList n'est pas nécessaire, il suffit de déclarer dans le viewmodel la liste de personnes avec le type ObservableCollection<PersonName>

    Pour le point 2, Le seul moyen qu'a la vue de modifier les données est d'ajouter un converter au binding (classe qui implémente IValueConverter). Quand j'ai besoin de formater des données qui ne sont utilisées que pour l'affichage, je définis des propriétés en lecture seule qui mettent en forme les données (voir l'exemple plus haut)

    il faut penser cependant à prévenir la vue que la propriété doit être rafraichie lorsque la liste privée a changée ses éléments:

    ListeNomsInterne.CollectionChanged += (s, e) => 
    {
        if (PropertyChanged != null) 
        {
            PropertyChanged(this, new PropertyChangedEventArgs("ListeTriee"));
        }
    }


    mardi 18 décembre 2012 23:24
  • Bonjour,

    Est-ce que vous avez testé les solutions proposées ? Merci de partager avec nous les résultats, afin que d'autres personnes avec le même problème puissent profiter de cette solution.

    Cordialement,

    Aurel


    Aurel BERA, Microsoft
    Microsoft propose ce service gratuitement, dans le but d'aider les utilisateurs et d'élargir les connaissances générales liées aux produits et technologies Microsoft. Ce contenu est fourni "tel quel" et il n'implique aucune responsabilité de la part de Microsoft.

    mercredi 19 décembre 2012 11:20
  • Ajouter une propriété au ViewModele qui renvoie les données dans l'ordre voulu fonctionne tout a fait.

    Par contre je ne vois pas dans ce cas pas l' utilité du CollectionViewSource.

    Merci pour les réponses.

    mercredi 19 décembre 2012 19:38