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 :

[WPF] Grouper par propriété d'une sous-collection


Sujet :

Windows Presentation Foundation

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Mai 2007
    Messages
    32
    Détails du profil
    Informations forums :
    Inscription : Mai 2007
    Messages : 32
    Par défaut [WPF] Grouper par propriété d'une sous-collection
    J'ai (à nouveau) une super bonne question à poser aux gourous

    Allons dans le code directement, ça sera plus simple :

    Voici les différentes classes utilisées :

    Classe Lecteur
    Propriétés :
    Lecteur_Nom string
    Lecteur_Dossiers ObservableCollection<Dossier>

    Classe Dossier
    Propriétés :
    Dossier_Nom string
    Dossier_DateCrea DateTime


    J'ai dans ma Form une ObservableCollection<Lecteur> (appelée collecLecteurs) que je binde à un ItemsControl.

    Pour pouvoir afficher ma liste de Lecteurs avec sous chacun d'entre eux la liste des dossiers, j'utilise les ControlTemplates suivants :

    Template des Lecteurs :

    <ControlTemplate TargetType="{x:Type ItemsControl}" x:Key="ItemsControlTemplate_Lecteurs">
    <StackPanel Orientation="Vertical" x:Name="stack_Lecteurs" IsItemsHost="True" ClipToBounds="False" />
    </ControlTemplate>

    <DataTemplate x:Key="LecteurDataTemplate">
    <StackPanel>

    <Border BorderThickness="1" BorderBrush="Black">
    <StackPanel Orientation="Horizontal">
    <TextBlock Text="Disque " Margin="10" />
    <TextBlock x:Name="Lecteur_Letter" Text="{Binding Mode=OneWay, Path=Lecteur_Nom}" Margin="10" />
    </StackPanel>
    </Border>

    <ItemsControl x:Name="lst_Dossiers" ItemsSource="{Binding Mode=OneWay, Path= Lecteur_Dossiers}" Style="{DynamicResource ItemsControlStyle_Dossier}" />

    </StackPanel>
    </DataTemplate>

    <Style TargetType="{x:Type ItemsControl}" x:Key="ItemsControlStyle_Lecteur">
    <Setter Property="Template" Value="{DynamicResource ItemsControlTemplate_Lecteurs}"/>
    <Setter Property="ItemTemplate" Value="{DynamicResource LecteurDataTemplate}"/>
    </Style>
    Template des Dossiers :

    <ControlTemplate TargetType="{x:Type ItemsControl}" x:Key="ItemsControlTemplate_Dossiers">
    <StackPanel Orientation="Vertical" FlowDirection="LeftToRight" x:Name="stack_Dossiers" IsItemsHost="True"/>
    </ControlTemplate>

    <DataTemplate x:Key="DossierDataTemplate">
    <TextBlock x:Name="Dossier_Name" Text="{Binding Mode=OneWay, Path=Dossier_Nom}" />
    </DataTemplate>

    <Style TargetType="{x:Type ItemsControl}" x:Key="ItemsControlStyle_Dossier">
    <Setter Property="Template" Value="{DynamicResource ItemsControlTemplate_Dossiers}"/>
    <Setter Property="ItemTemplate" Value="{DynamicResource DossierDataTemplate}"/>
    </Style>
    J'affecte ma collection de lecteurs à l'ItemsControl via le code :

    XAML :
    <ItemsControl x:Name="lst_Lecteurs" Style="{DynamicResource ItemsControlStyle_Lecteur}" VirtualizingStackPanel.IsVirtualizing="True" />

    CS :
    lst_Lecteurs.ItemsSource = collecLecteurs;


    Jusqu'ici tout va bien, sauf que je souhaite grouper mes lecteurs par date de création...

    Avec le code ci-dessus, j'obtiens un truc du genre :

    ___________________________
    | Lecteur C
    ___________________________
    | Dossier 1
    | Dossier 2
    | Dossier 3
    | Dossier 4
    | Dossier 5
    | Dossier 6
    | Dossier 7
    | Dossier 8
    ___________________________
    | Lecteur D
    ___________________________
    | Dossier 1
    | Dossier 2
    | Dossier 3
    | Dossier 4
    | Dossier 5
    | Dossier 6
    | Dossier 7
    | Dossier 8
    ___________________________


    Ce que j'aimerais faire c'est :


    ___________________________
    | Lecteur C
    ----------------------------
    | MAI 2006
    ----------------------------
    | Dossier 1
    | Dossier 2
    | Dossier 3
    ----------------------------
    | AVRIL 2006
    ----------------------------
    | Dossier 4
    | Dossier 5
    | Dossier 6
    ----------------------------
    | MARS 2006
    ----------------------------
    | Dossier 7
    | Dossier 8
    ___________________________
    | Lecteur C
    ----------------------------
    | SEPTEMBRE 2006
    ----------------------------
    | Dossier 1
    | Dossier 2
    | Dossier 3
    | Dossier 4
    ----------------------------
    | AOUT 2006
    ----------------------------
    | Dossier 5
    | Dossier 6
    | Dossier 7
    | Dossier 8
    ___________________________

    Ceci en me basant sur la propriété Dossier_DateCrea des objets Dossier.

    En fait, j'appelle à l'aide car je n'arrive pas à utiliser les CollectionViewSource avec mon binding pour grouper mes objets Dossier dans mon template par Date.

    Y'aurait-il une autre solution que de passer par une CollectionViewSource ? Ou peut-être, comme guitoux qui a eu un problème similaire, utiliser une SortedList qui implémenterait INotifyCollectionChanged ?

    Une idée les amis ?

  2. #2
    Rédacteur
    Avatar de Thomas Lebrun
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    9 161
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 9 161
    Par défaut
    Citation Envoyé par BruceWayne
    Y'aurait-il une autre solution que de passer par une CollectionViewSource ?
    Non, je ne pense pas si tu veux grouper...

  3. #3
    Membre averti
    Inscrit en
    Mai 2007
    Messages
    32
    Détails du profil
    Informations forums :
    Inscription : Mai 2007
    Messages : 32
    Par défaut
    Bon, j'ai regardé comment fonctionne le regroupement via une CollectionViewSource, mais j'ai un drôle de problème : tout fonctionne nickel au niveau du grouping sauf 1 truc, le Binding au niveau du HeaderTemplate ! Je n'arrive pas à afficher la date des dossiers dans ce header.

    Voici la source :


    CODE XAML :


    <Window x:Class="Sorting_Collections.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Sorting_Collections" Height="300" Width="300"
    >

    <Grid>
    <ItemsControl x:Name="lst_Lecteurs" VirtualizingStackPanel.IsVirtualizing="True">

    <ItemsControl.ItemTemplate>
    <HierarchicalDataTemplate>
    <StackPanel Orientation="Horizontal">
    <TextBlock Text="{Binding Path=Dossier_Nom}" Margin="0,0,15,0" />
    <TextBlock Text="{Binding Path=Dossier_DateCreation}" />
    </StackPanel>
    </HierarchicalDataTemplate>
    </ItemsControl.ItemTemplate>

    <ItemsControl.GroupStyle>
    <GroupStyle>
    <GroupStyle.ContainerStyle>
    <Style TargetType="{x:Type GroupItem}">
    <Setter Property="Template">
    <Setter.Value>
    <ControlTemplate TargetType="{x:Type GroupItem}">
    <StackPanel>
    <TextBlock Text="Binding qui marche pô" Margin="10" Width="150" HorizontalAlignment="Left" Background="GreenYellow" />
    <ItemsPresenter />
    </StackPanel>
    </ControlTemplate>
    </Setter.Value>
    </Setter>
    </Style>
    </GroupStyle.ContainerStyle>
    </GroupStyle>
    </ItemsControl.GroupStyle>
    </ItemsControl>
    </Grid>


    </Window>

    CODE BEHIND :


    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Shapes;
    using System.Collections.ObjectModel;
    using PhoxKitV2_Lib.Entities.Photo;
    using PhoxKitV2_Lib.Helpers;
    using System.ComponentModel;
    using System.Globalization;


    namespace Sorting_Collections
    {
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>

    public partial class Window1 : System.Windows.Window
    {


    private ObservableCollection<PhoxKitV2_Lib.Entities.Photo.Lecteur> collec_Lecteurs = new ObservableCollection<PhoxKitV2_Lib.Entities.Photo.Lecteur>();


    public Window1()
    {
    InitializeComponent();

    this.Loaded += new RoutedEventHandler(Window1_Loaded);
    }

    void Window1_Loaded(object sender, RoutedEventArgs e)
    {

    Lecteur lec = new Lecteur();
    lec.Lecteur_Collec_Dossiers = new ObservableCollection<Dossier>();
    //lec.Lecteur_Collec_Dossiers_Dispatch = new DispatchingCollection<ObservableCollection<Dossier>, Dossier>(lec.Lecteur_Collec_Dossiers, this.Dispatcher);
    lec.Lecteur_Lettre = 1.ToString().ToCharArray()[0];

    for (int i = 1; i < 10; i++)
    {
    Dossier doss = new Dossier();
    doss.Dossier_DateCreation = new DateTime(2006, i, 25);
    doss.Dossier_Path = "path_" + i.ToString();
    doss.Dossier_Nom = "Dossier " + i.ToString();
    lec.Lecteur_Collec_Dossiers.Add(doss);
    }

    for (int i = 1; i < 10; i++)
    {
    Dossier doss = new Dossier();
    doss.Dossier_DateCreation = new DateTime(2006, 2, 25);
    doss.Dossier_Path = "path_" + (i+1).ToString();
    doss.Dossier_Nom = "Dossier " + i.ToString();
    lec.Lecteur_Collec_Dossiers.Add(doss);
    }

    for (int i = 1; i < 10; i++)
    {
    Dossier doss = new Dossier();
    doss.Dossier_DateCreation = new DateTime(2006, 4, 25);
    doss.Dossier_Path = "path_5";
    doss.Dossier_Nom = "Dossier " + i.ToString();
    lec.Lecteur_Collec_Dossiers.Add(doss);
    }


    ICollectionView view = CollectionViewSource.GetDefaultView(lec.Lecteur_Collec_Dossiers);
    view.GroupDescriptions.Clear();
    view.GroupDescriptions.Add(new PropertyGroupDescription("Dossier_DateCreation", new DateTimeToDateConverter()));

    this.lst_Lecteurs.ItemsSource = lec.Lecteur_Collec_Dossiers;

    }

    }



    public class DateTimeToDateConverter : IValueConverter
    {
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
    return ((DateTime)value).ToString("MM/dd/yyyy");
    }
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
    throw new NotSupportedException();
    }
    }


    }


    Voici ce que ça donne à l'exécution :

    http://www.developpez.net/forums/att...1&d=1181748146

    On voit ici le "Binding qui marche pô", si je lui mets :

    <TextBlock Text="{Binding Path=Dossier_DateCreation}" Margin="10" Width="150" HorizontalAlignment="Left" Background="GreenYellow" />

    à la place de :

    <TextBlock Text="Binding qui marche pô" Margin="10" Width="150" HorizontalAlignment="Left" Background="GreenYellow" />

    Voici ce que ça donne :

    http://www.developpez.net/forums/att...1&d=1181748434

    Râaaaah...y'a toujours un truc qui va pas...j'ai essayé en externalisant les DataTemplates, mais le Binding sur le HeaderTemplate du GroupStyle ne fonctionne pas non plus.

    Je sens que je suis pas loin, mais j'ai peut-être oublié un truc dans mon code ? Peut-être une assignation de Binding ou j'ai oublié un truc dans la création de ma CollectionViewSource ?
    Images attachées Images attachées   

  4. #4
    Rédacteur
    Avatar de Thomas Lebrun
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    9 161
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 9 161
    Par défaut
    Tu as essayé avec:

    <TextBlock Text="{Binding Path=Dossier_DateCreation}" Margin="10" Width="150" HorizontalAlignment="Left" Background="GreenYellow" />


    Sinon, faudrait essayer de faire ton Binding en utilisant AncestorLevel

  5. #5
    Membre averti
    Inscrit en
    Mai 2007
    Messages
    32
    Détails du profil
    Informations forums :
    Inscription : Mai 2007
    Messages : 32
    Par défaut
    C'est justement ce code là qui ne marche pas, et je ne vois pas du tout pourquoi l'info n'est pas transmise au DataTemplate...

    Je vais voir du côté d'ancestor level alors. Merci je fais un retour

    ++

  6. #6
    Rédacteur
    Avatar de Thomas Lebrun
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    9 161
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 9 161
    Par défaut
    Pardon, je voulais parler du code suivant:

    <TextBlock Text="{TemplateBinding Path=Dossier_DateCreation}" Margin="10" Width="150" HorizontalAlignment="Left" Background="GreenYellow" />


    Sinon, des nouvelles du coté de AncestorLevel ou AncestorType ?

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 29/06/2015, 16h01
  2. [WPF] Valeur par défaut d'une DependencyProperty n'appelle pas le callback
    Par HanLee dans le forum Windows Presentation Foundation
    Réponses: 2
    Dernier message: 01/04/2010, 21h36
  3. grouper par mois dans une listview
    Par superkiller dans le forum Windows Presentation Foundation
    Réponses: 3
    Dernier message: 24/01/2010, 14h25
  4. Valeur par défaut dans une sous forme
    Par lvr dans le forum IHM
    Réponses: 2
    Dernier message: 23/08/2008, 11h51
  5. [WPF] Comment binder une sous-collection d'une collection ?
    Par BruceWayne dans le forum Windows Presentation Foundation
    Réponses: 5
    Dernier message: 04/06/2007, 16h55

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