locked
Ajout automatique de textblock dans une listbox RRS feed

  • Question

  • Bonjour,

    mon appli dispose d'une listbox contenant plusieurs éléments bindés (ajoutés par l'utilisateur), chacun ayant un champ "date".

    Est-il possible de catégoriser ces éléments automatiquement, par date, je m'explique :

     

    si ma liste contient plusieurs éléments comme ceci :

    - item 1 (date : aujourd'hui)

    - item 2 (date : aujourd'hui)

    - item 3 (date : demain)

     

    je voudrais que des textblocks soient automatiquement ajoutés comme cela :

    ----- TextBlock Text="Aujourd'hui"

    - item 1 (date : aujourd'hui)

    - item 2 (date : aujourd'hui)

    ----- TextBlock Text="Demain"

    - item 3 (date : demain)

     

    Merci d'avance, j'espère avoir été assez clair :)

     

     

    Cordialement,

    Marc.

    dimanche 17 avril 2011 12:54

Réponses

  • Bonjour,

     

    Désolé pour le délai de réponse, mais j'étais en déplacement.

    Voici le code adapté pour votre exemple Dans le code C# :

    void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
          todoElementList = IsolatedStorageHelper.GetObject<List<TodoElement>>("ListeTodo");
    
          listbox.ItemsSource = listTodo.OrderBy(todoElement => Convert.ToDateTime(todoElement.TodoDateTime));
    
          List<MaCollection> collections = new List<MaCollection>();
          //On parcourt ta collection de TodoElement
          //Pour créer une collection qui va nous permettre de créer un groupe dans la listBox
          //Par date
          foreach (TodoElement todoElement in listTodo)
          {
            //On vérifie si la nouvelle collection contient déjà un objet MaCollection avec une date existant sur un des todoElement
            MaCollection macol = collections.FirstOrDefault(col => col.Date == todoElement.TodoDateTime);
            if (macol != null)
            {
              //Si oui on ajoute le TodoElement à l'objet existant
              macol.Libelles.Add(todoElement);
            }
            else
            {
              //Si non on crée un nouvel objet MaCollection
              macol = new MaCollection();
              macol.Date = todoElement.TodoDateTime;
              macol.Libelles = new List<TodoElement>();
              macol.Libelles.Add(todoElement);
              collections.Add(macol);
            }
          }
          listbox.ItemsSource = collections;
        }
    

     

    voici les classe à ajouter dans le code C# :

    public class MaCollection
      {
        public List<TodoElement> Libelles { get; set; }
    
        public DateTime Date { get; set; }
      }
    
      public class DateTimeToStringConverter : IValueConverter
      {
    
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
          String sChaineRetour = null;
          if (value is DateTime)
          {
            DateTime dt = (DateTime)value;
            if (dt == DateTime.Now.Date)
              sChaineRetour = "Aujourd'hui";
            else if (dt == DateTime.Now.AddDays(-1).Date)
              sChaineRetour = "Hier";
            else if (dt == DateTime.Now.AddDays(1).Date)
              sChaineRetour = "Demain";
            else
              sChaineRetour = dt.ToShortDateString();
          }
    
          return sChaineRetour;
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
          throw new NotImplementedException();
        }
      }
    
    
    

     

     

     

     


    Cordialement, Pascal.

    Développeur Wpf/SilverLight/WinPhone7

    samedi 23 avril 2011 09:29
  • Et dans le code Xaml voici ce qu'il faut déclarer :

    <ListBox x:Name="listbox">
            <ListBox.ItemTemplate>
              <DataTemplate >
                <Grid>
                  <Grid.RowDefinitions>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="*"/>
                  </Grid.RowDefinitions>
                  <TextBlock Text="{Binding Date, Converter={StaticResource myDateTimeToStringConverter}}" FontWeight="Bold" Grid.Row="0"/>
                  <ListBox ItemsSource="{Binding Libelles}" Grid.Row="1">
                    <ListBox.ItemTemplate>
                      <DataTemplate >
                        <TextBlock Text="{Binding Todo}" />
                      </DataTemplate>
                    </ListBox.ItemTemplate>
                  </ListBox>
                </Grid>
    
              </DataTemplate>
            </ListBox.ItemTemplate>
          </ListBox>
    

     

    Et au dessus dans les ressources xaml de la page voici ce qu'il faut déclarer :

     

    <!-- et dans les déclarations ajouter cela -->
    xmlns:local="clr-namespace:WindowsPhoneApplication3"
    <!--A la place de WindowsPhoneApplication3 mettre le namespace de votre application -->
    
    
    <Grid.Resources>
          <local:DateTimeToStringConverter x:Key="myDateTimeToStringConverter"/>
        </Grid.Resources>
    

     

    Voila j'espère que cela va vous aider.

     


    Cordialement, Pascal.

    Développeur Wpf/SilverLight/WinPhone7

    samedi 23 avril 2011 09:33

Toutes les réponses

  • Bonjour,

     

    j'allais vous répondre qu'il vous suffit d'implémenter ListBox.GroupStyle, habitude prise en WPF mais je viens de décourvrir que l'on ne peut pas le faire en Winphone 7.

    Donc voici un exemple avec un moyen de contournement :

    public partial class MainPage : PhoneApplicationPage
      {
        // Constructeur
        public MainPage()
        {
          InitializeComponent();
          this.Loaded += new RoutedEventHandler(MainPage_Loaded);
        }
    
        void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
          List<MaClasse> liste = new List<MaClasse>();
          MaClasse c1 = new MaClasse() { Libelle = "New 1", Date = DateTime.Now.AddDays(-1).Date };
          liste.Add(c1);
          MaClasse c2 = new MaClasse() { Libelle = "New 2", Date = DateTime.Now.AddDays(1).Date };
          liste.Add(c2);
          MaClasse c3 = new MaClasse() { Libelle = "New 3", Date = DateTime.Now.Date };
          liste.Add(c3);
          MaClasse c4 = new MaClasse() { Libelle = "New 4", Date = DateTime.Now.AddDays(-1).Date };
          liste.Add(c4);
          List<MaCollection> collections = new List<MaCollection>();
          foreach (MaClasse classe in liste)
          {
            MaCollection macol = collections.FirstOrDefault(col => col.Date == classe.Date);
            if (macol != null)
            {
              macol.Libelles.Add(classe);
            }
            else
            {
              macol = new MaCollection();
              macol.Date = classe.Date;
              macol.Libelles = new List<MaClasse>();
              macol.Libelles.Add(classe);
              collections.Add(macol);
            }
          }
          lb1.ItemsSource = collections;
        }
      }
    
      public class MaClasse
      {
        public String Libelle { get; set; }
    
        public DateTime Date { get; set; }
      }
    
      public class MaCollection
      {
        public List<MaClasse> Libelles { get; set; }
    
        public DateTime Date { get; set; }
      }
    

     

     et voici le xaml :

    <ListBox x:Name="lb1">
            <ListBox.ItemTemplate>
              <DataTemplate >
                <Grid>
                  <Grid.RowDefinitions>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="*"/>
                  </Grid.RowDefinitions>
                  <TextBlock Text="{Binding Date}" FontWeight="Bold" Grid.Row="0"/>
                  <ListBox ItemsSource="{Binding Libelles}" Grid.Row="1">
                    <ListBox.ItemTemplate>
                      <DataTemplate >
                        <TextBlock Text="{Binding Libelle}" />
                      </DataTemplate>
                    </ListBox.ItemTemplate>
                  </ListBox>
                </Grid>
                
              </DataTemplate>
            </ListBox.ItemTemplate>
          </ListBox>
    


    Cordialement, Pascal.

    Développeur Wpf/SilverLight/WinPhone7

    dimanche 17 avril 2011 15:23
  • J'allais oublié pour afficher Demain ou Aujourd'hui voila un exemple de Converter :

    public class DateTimeToStringConverter : IValueConverter
      {
    
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
          String sChaineRetour = null;
          if (value is DateTime)
          {
            DateTime dt = (DateTime)value;
            if (dt == DateTime.Now.Date)
              sChaineRetour = "Aujourd'hui";
            else if (dt == DateTime.Now.AddDays(-1).Date)
              sChaineRetour = "Hier";
            else if (dt == DateTime.Now.AddDays(1).Date)
              sChaineRetour = "Demain";
            else
              sChaineRetour = dt.ToShortDateString();
          }
    
          return sChaineRetour;
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
          throw new NotImplementedException();
        }
      }
    

     

    et voici ce qu'il faut mettre dans le xaml :

    <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
          <Grid.Resources>
            <local:DateTimeToStringConverter x:Key="myDateTimeToStringConverter"/>
          </Grid.Resources>
          <!--<Image Source="Background.png" Width="32"/>-->
          <ListBox x:Name="lb1">
            <ListBox.ItemTemplate>
              <DataTemplate >
                <Grid>
                  <Grid.RowDefinitions>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="*"/>
                  </Grid.RowDefinitions>
                  <TextBlock Text="{Binding Date, Converter={StaticResource myDateTimeToStringConverter}}" FontWeight="Bold" Grid.Row="0"/>
                  <ListBox ItemsSource="{Binding Libelles}" Grid.Row="1">
                    <ListBox.ItemTemplate>
                      <DataTemplate >
                        <TextBlock Text="{Binding Libelle}" />
                      </DataTemplate>
                    </ListBox.ItemTemplate>
                  </ListBox>
                </Grid>
                
              </DataTemplate>
            </ListBox.ItemTemplate>
          </ListBox>
        </Grid>
    

     


    Cordialement, Pascal.

    Développeur Wpf/SilverLight/WinPhone7

    • Proposé comme réponse Pascal Saille dimanche 17 avril 2011 15:33
    dimanche 17 avril 2011 15:33
  • Merci Pascal pour ta réactivité et la qualité de ta réponse :)

    Cependant je suis novice dans le domaine, et je galère un peu...

     

    Peux-tu m'aider à intégrer ta solution à mon code déjà en place ?

    Voici ce que j'ai dans le MainPage.xaml.cs :

     

    List<TodoElement> todoElementList;
    ObservableCollection<TodoElement> listTodo = new ObservableCollection<TodoElement>();
    

     

    Dans MainPage_Loaded je charge ma liste comme suit :

     

    todoElementList = IsolatedStorageHelper.GetObject<List<TodoElement>>("ListeTodo");
    
    listbox.ItemsSource = listTodo.OrderBy(todoElement => Convert.ToDateTime(todoElement.TodoDateTime));
    

    Et mon xaml se présente de la façon suivante :

     

    <controls:PanoramaItem Header=" ">
            <Grid>
              <ListBox x:Name="listbox">
                <ListBox.ItemTemplate>
                  <DataTemplate>
                    <StackPanel>
                      <StackPanel>
                        <TextBlock Text="{Binding Todo}" />
                      </StackPanel>
    
                      <StackPanel Margin="0">
                        <TextBlock Text="{Binding TodoDateTime, Converter={StaticResource dateConverter}}" />
                      </StackPanel>
                    </StackPanel>
                  </DataTemplate>
                </ListBox.ItemTemplate>
              </ListBox>
            </Grid>
    </controls:PanoramaItem>
    

     

    Merci pour ton aide !

     

    Cordialement,

    Marc.

    mardi 19 avril 2011 21:02
  • Bonjour,

     

    Désolé pour le délai de réponse, mais j'étais en déplacement.

    Voici le code adapté pour votre exemple Dans le code C# :

    void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
          todoElementList = IsolatedStorageHelper.GetObject<List<TodoElement>>("ListeTodo");
    
          listbox.ItemsSource = listTodo.OrderBy(todoElement => Convert.ToDateTime(todoElement.TodoDateTime));
    
          List<MaCollection> collections = new List<MaCollection>();
          //On parcourt ta collection de TodoElement
          //Pour créer une collection qui va nous permettre de créer un groupe dans la listBox
          //Par date
          foreach (TodoElement todoElement in listTodo)
          {
            //On vérifie si la nouvelle collection contient déjà un objet MaCollection avec une date existant sur un des todoElement
            MaCollection macol = collections.FirstOrDefault(col => col.Date == todoElement.TodoDateTime);
            if (macol != null)
            {
              //Si oui on ajoute le TodoElement à l'objet existant
              macol.Libelles.Add(todoElement);
            }
            else
            {
              //Si non on crée un nouvel objet MaCollection
              macol = new MaCollection();
              macol.Date = todoElement.TodoDateTime;
              macol.Libelles = new List<TodoElement>();
              macol.Libelles.Add(todoElement);
              collections.Add(macol);
            }
          }
          listbox.ItemsSource = collections;
        }
    

     

    voici les classe à ajouter dans le code C# :

    public class MaCollection
      {
        public List<TodoElement> Libelles { get; set; }
    
        public DateTime Date { get; set; }
      }
    
      public class DateTimeToStringConverter : IValueConverter
      {
    
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
          String sChaineRetour = null;
          if (value is DateTime)
          {
            DateTime dt = (DateTime)value;
            if (dt == DateTime.Now.Date)
              sChaineRetour = "Aujourd'hui";
            else if (dt == DateTime.Now.AddDays(-1).Date)
              sChaineRetour = "Hier";
            else if (dt == DateTime.Now.AddDays(1).Date)
              sChaineRetour = "Demain";
            else
              sChaineRetour = dt.ToShortDateString();
          }
    
          return sChaineRetour;
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
          throw new NotImplementedException();
        }
      }
    
    
    

     

     

     

     


    Cordialement, Pascal.

    Développeur Wpf/SilverLight/WinPhone7

    samedi 23 avril 2011 09:29
  • Et dans le code Xaml voici ce qu'il faut déclarer :

    <ListBox x:Name="listbox">
            <ListBox.ItemTemplate>
              <DataTemplate >
                <Grid>
                  <Grid.RowDefinitions>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="*"/>
                  </Grid.RowDefinitions>
                  <TextBlock Text="{Binding Date, Converter={StaticResource myDateTimeToStringConverter}}" FontWeight="Bold" Grid.Row="0"/>
                  <ListBox ItemsSource="{Binding Libelles}" Grid.Row="1">
                    <ListBox.ItemTemplate>
                      <DataTemplate >
                        <TextBlock Text="{Binding Todo}" />
                      </DataTemplate>
                    </ListBox.ItemTemplate>
                  </ListBox>
                </Grid>
    
              </DataTemplate>
            </ListBox.ItemTemplate>
          </ListBox>
    

     

    Et au dessus dans les ressources xaml de la page voici ce qu'il faut déclarer :

     

    <!-- et dans les déclarations ajouter cela -->
    xmlns:local="clr-namespace:WindowsPhoneApplication3"
    <!--A la place de WindowsPhoneApplication3 mettre le namespace de votre application -->
    
    
    <Grid.Resources>
          <local:DateTimeToStringConverter x:Key="myDateTimeToStringConverter"/>
        </Grid.Resources>
    

     

    Voila j'espère que cela va vous aider.

     


    Cordialement, Pascal.

    Développeur Wpf/SilverLight/WinPhone7

    samedi 23 avril 2011 09:33
  • Bonjour, Kemar2012,

    Avez-vous réussi à tester la solution de Pascal ? Merci pour partager avec nous les résultats, afin que d'autres personnes avec le même problème puissent profiter de cette solution.

     

    Bonne journée,

    Cipri

     


    Suivez MSDN sur Twitter   Suivez MSDN sur Facebook


    Ciprian DUDUIALA, MSFT  
    •Nous vous prions de considérer que dans le cadre de ce forum on n’offre pas de support technique et aucune garantie de la part de Microsoft ne peut être offerte.

    mercredi 27 avril 2011 07:00