Reorganiser une list d'object

Résolu
dragonfly22000
Messages postés
49
Date d'inscription
mardi 11 décembre 2018
Statut
Membre
Dernière intervention
13 avril 2021
- 11 avril 2021 à 12:40
Whismeril
Messages postés
17336
Date d'inscription
mardi 11 mars 2003
Statut
Modérateur
Dernière intervention
20 mai 2022
- 14 avril 2021 à 17:47
Bonjour,
je me trouve face a un petit problème.
J'ai un Model Mur et un Model Brique;
Mon Mur a une propriété int Height et int Width.
Ma brique a une propriété int Id.
Quant je rentre 2 dans Height et 10 dans Width ,ça fabrique un mur de 2 briques de haut sur 10 de large et en même temps ça me rempli une observable collection de 20 Briques.
Ma collection de brique bind une uniformgrid.

Jusqu'ici tout va bien j’obtiens bien le visuel que je veux:


Ma liste brique est trier par Id comme ceci = (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20).
J'aurais voulu pouvoir re-trier ou recréer une autre liste pour qu'elle ressemble a ça:
1,11,2,12,3,13,4,14,5,15,6,16,7,17,8,18,9,19,10,20...........).
En gros refaire une liste mais avec un ordre de sélection vertical des Id.

J'ai essayer plusieurs chose savant de vous solliciter (for ,foreach ,linq) en vain.

Merci d'avance pour vos réponses .
bonne journée.

9 réponses

Whismeril
Messages postés
17336
Date d'inscription
mardi 11 mars 2003
Statut
Modérateur
Dernière intervention
20 mai 2022
596
11 avril 2021 à 18:23
D'abord simplifions un peu la génération de ta collection
            for (int i = 0; i < 6; i++) 
            {
                Brique b = new Brique { Id = i + 1 };//En une ligne tu instancies et affecte la propriété Id

                VisualBrique.Add(b);
            }

Ensuite, si l'effet recherché n'est que visuel, tu peux utiliser un ItemsControl wrappé verticalement
        <ItemsControl ItemsSource="{Binding VisualBrique}" Height="65" Width="45">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <WrapPanel Orientation="Vertical"/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Border BorderThickness="2" Height="20" Width="20" BorderBrush="Red" Background="LightGray">
                        <TextBlock Text="{Binding Id}" Foreground="White"/>
                    </Border>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>




Bien sûr on peut s'arranger pour faire en sorte que la taille (et par extension le nombre de lignes et de colonnes) soit bindable.
Mais avant d'aller plus loin confirme moi si ça te convient.
1
Whismeril
Messages postés
17336
Date d'inscription
mardi 11 mars 2003
Statut
Modérateur
Dernière intervention
20 mai 2022
596
12 avril 2021 à 12:12
Impec.

Pense à marquer le sujet résolu.
1
Whismeril
Messages postés
17336
Date d'inscription
mardi 11 mars 2003
Statut
Modérateur
Dernière intervention
20 mai 2022
596
11 avril 2021 à 12:59
Bonjour

pour pouvoir essayer de t'aider, il faut comprendre la logique tu tri.
Or là ça ne saute pas aux yeux.
Peux tu expliquer cette logique?

0
dragonfly22000
Messages postés
49
Date d'inscription
mardi 11 décembre 2018
Statut
Membre
Dernière intervention
13 avril 2021

11 avril 2021 à 13:52
Salut Whismeril
Ok Je vais essayer de mieux m'exprimer.

J'ai une boucle for qui me permet de remplir une observable collection (VisualBrique)
  public void DrawWall()
        {
            VisualBrique.Clear();

            for (int i = 0; i < 6; i++)  ////6 pour simplifier l'exemple en fait = (Height=2 X Width=3 propriété du mur)
            {
                Brique b = new Brique();
                b.Id = i + 1;

                VisualBrique.Add(b);
            }
        }

Ce qui me donne un visuel comme ceci:


Je me retrouve donc avec une liste VisualBrique qui contient mes objet dans l'ordre des Id (trier de gauche a droite) =
brique[0].id=1 ,
brique[1].id=2,
brique[2].id=3,
brique[3].id=4,
brique[4].id=5,
brique[5].id=6

Moi j'aurais voulu soit refaire une nouvelle liste soit trier VisualBrique pour obtenir ceci (trier de haut en bas).
brique[0].id=1 ,
brique[1].id=4,
brique[2].id=2,
brique[3].id=5,
brique[4].id=3,
brique[5].id=6

J’espère que c'est plus clair n’hésite pas a me dire si tu comprends toujours rien a mon charabia.
Merci d'avance.
0
vb95
Messages postés
2630
Date d'inscription
samedi 11 janvier 2014
Statut
Modérateur
Dernière intervention
19 mai 2022
151 > dragonfly22000
Messages postés
49
Date d'inscription
mardi 11 décembre 2018
Statut
Membre
Dernière intervention
13 avril 2021

Modifié le 11 avril 2021 à 22:21
Bonjour à vous deux
Pour dragonfly22000
            VisualBrique.Clear();
            for (int i = 0; i < Mur.Height * Mur.Width; i++)
            {
                Brique b = new Brique { Id = i + 1 };
                VisualBrique.Add(b);
            }
            // code à rajouter
            int Idbrique;
            int NombreImpair = Mur.Width - 1;
            int NombrePair = 0;
            for (int i = 0; i < VisualBrique.Count -1; i += 2)
            {
                Idbrique = VisualBrique[i].Id;
                Idbrique -= NombrePair;
                VisualBrique[i].Id = Idbrique;
                Idbrique = VisualBrique[i + 1].Id;
                Idbrique += NombreImpair;
                VisualBrique[i + 1].Id = Idbrique;
                NombreImpair--;
                NombrePair++;
            }


J'ai testé chez moi et cela fonctionne . Attention Mur.Height doit toujours être = à 2

voici le code complet du projet qui a servi pour ce problème
using System.Collections.Generic;
using System.Windows.Forms;

namespace Test
{
    public partial class Form1 : Form
    {
        private List<Brique> VisualBrique = new List<Brique>();
        
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, System.EventArgs e)
        {
            Mur M = new Mur { Height = 2, Width = 5 }; // un mur en largeur et hauteur ( on peut modifier la largeur uniquement )
            VisualBrique.Clear();
            for (int i = 0; i < M.Height * M.Width; i++)
            {
                Brique b = new Brique { Id = i + 1 };
                VisualBrique.Add(b);
            }
            int Idbrique;
            int NombreImpair = M.Width - 1;
            int NombrePair = 0;
            for (int i = 0; i < VisualBrique.Count -1; i += 2)
            {
                Idbrique = VisualBrique[i].Id;
                Idbrique -= NombrePair;
                VisualBrique[i].Id = Idbrique;
                Idbrique = VisualBrique[i + 1].Id;
                Idbrique += NombreImpair;
                VisualBrique[i + 1].Id = Idbrique;
                NombreImpair--;
                NombrePair++;
            }
        }

        public class Brique  
        {
            public int Id { get; set; }
        }

        public class Mur 
        {
            public int Width { get; set; }
            public int Height { get; set; }
        }
    }
}
0
Whismeril
Messages postés
17336
Date d'inscription
mardi 11 mars 2003
Statut
Modérateur
Dernière intervention
20 mai 2022
596 > vb95
Messages postés
2630
Date d'inscription
samedi 11 janvier 2014
Statut
Modérateur
Dernière intervention
19 mai 2022

11 avril 2021 à 23:10
Bonsoir VB

Au détail près qu’il est en WPF ;)
0
vb95
Messages postés
2630
Date d'inscription
samedi 11 janvier 2014
Statut
Modérateur
Dernière intervention
19 mai 2022
151 > Whismeril
Messages postés
17336
Date d'inscription
mardi 11 mars 2003
Statut
Modérateur
Dernière intervention
20 mai 2022

Modifié le 12 avril 2021 à 01:41
Salut Whis
D'accord pour le WPF . Mais le WPF est juste là pour la construction de l'interface graphique . Et moi je n'agis que sur la collection VisualBrique pour le code qu'il doit ajouter .
Mon projet lui est bien en Windows Forms classique . J'ai déjà essayer le WPF mais sans succès ( pire que les classes à mes débuts et dont je te remercie pour le prof que tu as été )
Dis-moi si je me trompe !
0
Whismeril
Messages postés
17336
Date d'inscription
mardi 11 mars 2003
Statut
Modérateur
Dernière intervention
20 mai 2022
596 > vb95
Messages postés
2630
Date d'inscription
samedi 11 janvier 2014
Statut
Modérateur
Dernière intervention
19 mai 2022

12 avril 2021 à 07:56
Non tu ne trompes pas et trier vraiment la collection est une solution.
0
Whismeril
Messages postés
17336
Date d'inscription
mardi 11 mars 2003
Statut
Modérateur
Dernière intervention
20 mai 2022
596
Modifié le 11 avril 2021 à 15:18
Comme ça?


Quand j'étais petit, la mer Morte n'était que malade.
George Burns
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
dragonfly22000
Messages postés
49
Date d'inscription
mardi 11 décembre 2018
Statut
Membre
Dernière intervention
13 avril 2021

11 avril 2021 à 15:39
Exactement .
0
Whismeril
Messages postés
17336
Date d'inscription
mardi 11 mars 2003
Statut
Modérateur
Dernière intervention
20 mai 2022
596
11 avril 2021 à 17:38
Et ben un p'tit dessin dès le début aurait été d'un grand secours ;)
0
dragonfly22000
Messages postés
49
Date d'inscription
mardi 11 décembre 2018
Statut
Membre
Dernière intervention
13 avril 2021

12 avril 2021 à 12:00
Salut Whismeril , merci pour le coup de main.
Au début je voulais vraiment changer l'ordre de ma liste avec une fonction.....
Après plusieurs heures de recherche et de brainstorming je me suis rendu compte que je me prenais la tête pour rien.
J'ai donc adopter ta solution à pars que mon itempaneltemplate est une Uniformgrid.
Le problème c'est qu'a la base ce composant ne possède pas de paramètre d'orientation mais en fouillant sur le net j'ai trouver une classe dérivé qui l' implémente....Youpi.
J'ai donc rajouté un Boleen(checkbox) lié a un converter afin que l'utilisateur puisse travailler horizontalement ou verticalement.
Merci encore pour moi c'est résolu.
Bonne journée a toi merci encore.
0
Whismeril
Messages postés
17336
Date d'inscription
mardi 11 mars 2003
Statut
Modérateur
Dernière intervention
20 mai 2022
596
13 avril 2021 à 19:57
Hello,
moi ce qui m'intéressait c'est de voir comment tu as fait avec l'Uniformgrid.
Parce qu'en fait, ça ne se binde pas.
Du coup avoir une observablecollection n'a (avec les éléments que j'ai) pas d'intérêt.
C'est d'ailleurs pour cette raison que je t'avais proposé une solution avec un panel.

0
dragonfly22000
Messages postés
49
Date d'inscription
mardi 11 décembre 2018
Statut
Membre
Dernière intervention
13 avril 2021

13 avril 2021 à 23:23
Salut Whismeril pas de soucis.
En fait l'uniformgrid me sert juste pour l'item panel template que je bind en hauteur(nombre de ligne) et largeur(nombre de colonne) .
Après ce sont mes item template que je bind a ma propriété Id.

 <ListBox ItemsSource="{Binding VisualBrique }"  
SelectionMode="Multiple"   Padding="-1" 
Margin="0" 
BorderThickness="0">
                                <ListBox.ItemsPanel>
                                    <ItemsPanelTemplate>
                                        <UniformGrid Rows="{Binding Height}"  Columns="{Binding Width}"  Margin="0" />
                                    </ItemsPanelTemplate>
                                </ListBox.ItemsPanel>
                                <ListBox.ItemContainerStyle>
                                    <Style TargetType="ListBoxItem">
                                        <Style.Triggers>
                                            <Trigger Property="IsSelected" Value="True">
                                                <Setter Property="Opacity" Value="0.1"/>
                                                <Setter Property="Background" Value="Transparent"/>
                                            </Trigger>
                                        </Style.Triggers>
                                        <Setter Property="Padding" Value="0"/>
                                        <Setter Property="Margin" Value="0"/>
                                        <Setter Property="BorderThickness" Value="10"/>
                                        <Setter Property="Background" Value="DarkGray"/>
                                        <Setter Property="BorderBrush" Value="Red"/>
                                        <Setter Property="Cursor" Value="Hand"/>
                                        <Setter Property="HorizontalContentAlignment" Value="Center"/>
                                        <Setter Property="IsSelected" Value="{Binding IsSelected}"/>
                                    </Style>
                                </ListBox.ItemContainerStyle>
                                <ListBox.ItemTemplate>
                                    <DataTemplate DataType="{x:Type vm:ViewBriqueViewModel}">
                                        <TextBox  Foreground="White" Text="{Binding Id}" FontSize="200"  VerticalContentAlignment="Center"  HorizontalContentAlignment="Center" IsReadOnly="True"    HorizontalAlignment="Stretch" VerticalAlignment="Center" Background="Transparent"   >
                                        </TextBox>
                                    </DataTemplate>
                                </ListBox.ItemTemplate>
                            </ListBox>


Ps:ViewBriqueViewModel est mon view model(classe) de "Brique".

Je te balance tout le code ,je sais pas si tu trouveras ça très clair n’hésite pas a me demander s'il y a un truc que tu capte pas.....Ça fait plaisir.
Pour une fois que je peux aider.
Bonne soirée
0
Whismeril
Messages postés
17336
Date d'inscription
mardi 11 mars 2003
Statut
Modérateur
Dernière intervention
20 mai 2022
596
14 avril 2021 à 17:47
OK.
C'est quasiment la même chose que je te proposais.
J'ai mis un itemscontrol comme contenant parce que tu n'avais parlait que de l'uniformgrid et j'avais supposé que tu ne voulais pas d'ascenceur.
Et comme paneltemplate j'ai pris le wrappannel car justement son but est de mettre à la suite les items à l'horizontale ou à la verticale.
0