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

C# Discussion :

Créer grille d'objet (btn, label, txtbox, etc) dynamiquement [Débutant]


Sujet :

C#

  1. #1
    Membre du Club
    Homme Profil pro
    Ingénieur
    Inscrit en
    Février 2015
    Messages
    66
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur

    Informations forums :
    Inscription : Février 2015
    Messages : 66
    Points : 63
    Points
    63
    Par défaut Créer grille d'objet (btn, label, txtbox, etc) dynamiquement
    Bonjour à tous,

    Je suis en train de coder une application, et je rencontre de nombreux problèmes (des difficiles, des simples) que j'arrive parfois a surmonter, mais là.. je me pose une colle.

    Dans un fichier txt, je récupère un certain nombre de ligne ( int count dans le code) compris entre 0 et 25.

    Coté XAML, j'ai une Grid de 5 colonnes et 5 lignes (voir image PJ)

    Je crée des objets dynamiques de la sorte suivante :

    Code : 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
     
    public void createGridButton()
            {
                int count = 2;  //récuperer le nb de ligne
     
                int nbColumn = 5;
                int nbRow = 5;
                List<Button> LBtn = new List<Button>();
     
                for (int i = 0; i < count; i++)
                {
                    Button btn = new Button();
                    LBtn.Add(btn);  
                    LBtn[i].Content = "Button " + i;
     
                    Grid.SetColumn(LBtn[i], i);
                    Grid.SetRow(LBtn[i], 0);
     
                    GridButton.Children.Add(LBtn[i]);
                }
            }
    Seulement, je n'arrive pas à générer plus que 5 boutons.
    Je n'arrive pas à parcourir ma grille selon les lignes et colonnes pour la génération dynamique.

    Je vous ajoute des images en PJ pour des cas si Count = 2, Count = 5 et Count = 7 pour que vous ayez une image du problème.

    Auriez-vous des éléments de réponses ?

    Zeratec
    Images attachées Images attachées     

  2. #2
    Membre éprouvé Avatar de WDKyle
    Homme Profil pro
    Analyste-Programmeur
    Inscrit en
    Septembre 2008
    Messages
    1 200
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste-Programmeur

    Informations forums :
    Inscription : Septembre 2008
    Messages : 1 200
    Points : 962
    Points
    962
    Par défaut
    Bonjour,

    Ta Grid n'évolue pas selon le nombre de Button, j'ai envie de dire que c'est donc normal. Elle reste à nbColumn = 5 donc cas typique de la dernière capture, les Button sont surement superposés dans la dernière colonne.

  3. #3
    Membre du Club
    Homme Profil pro
    Ingénieur
    Inscrit en
    Février 2015
    Messages
    66
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur

    Informations forums :
    Inscription : Février 2015
    Messages : 66
    Points : 63
    Points
    63
    Par défaut
    Oui, les boutons se superposent sur la dernière colonne de la première ligne.

    Le cas que je souhaite est, une fois 5 boutons sur une ligne, le suivant se mette à la ligne suivante (sorte de retour à la ligne en quelque sorte).

    Cest donc normal que les colonnes restent fixes dans la "Grid".

    C'est la logique du "retour à la ligne" que je n'arrive pas à transcrire dans mon code.

  4. #4
    Membre chevronné
    Homme Profil pro
    edi
    Inscrit en
    Juin 2007
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : edi

    Informations forums :
    Inscription : Juin 2007
    Messages : 898
    Points : 1 915
    Points
    1 915
    Par défaut
    Il aurait pu être utile d'avoir le code xaml de ta Grid pour voir comment tu fais le Binding. Et sinon tu peux regarder du côté de UniformGrid.

  5. #5
    Membre du Club
    Homme Profil pro
    Ingénieur
    Inscrit en
    Février 2015
    Messages
    66
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur

    Informations forums :
    Inscription : Février 2015
    Messages : 66
    Points : 63
    Points
    63
    Par défaut
    Justement, je ne souhaite pas binder la génération de bouton. En fait, je ne sais pas si c'est possible.

    J'ai trouvé une solution me permettant de générer, en fonction d'un nombre, des objets (btn, lbl, textbox, etc) dans une grille dont les dimensions sont prédéfinies.

    Code : 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
     
    public void createGridButton()
            {
                int count = 25;  //récuperer le nb de ligne du fichier texte (max 25)
                int nbColumn = 5; //nb de colonne de la grid
                int nbRow = 5; //nb de ligne de la grid
                int i = 0;
                int j = 0;
     
                List<Button> LBtn = new List<Button>();
     
                for (int k = 0; k < count; k++)
                {
                    if (k % nbColumn == 0 && k != 0)
                    {
                        j++;
                        i = 0;
                        if (j == nbRow) { j = 0; }
                    }
     
                    Button btn = new Button();
                    LBtn.Add(btn);
                    LBtn[k].Content = "Button " + k;
     
                    Grid.SetColumn(LBtn[k], i);
                    Grid.SetRow(LBtn[k], j);
     
                    GridButton.Children.Add(LBtn[k]);
     
                    i++;
                }
            }
    Je partage donc avec vous cette fonction pour ceux qui se pose la question de comment faire.

    Par ailleurs, je reste à l'écoute si une solution similaire est possible avec du binding.

    Zeratec

  6. #6
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 154
    Points : 25 072
    Points
    25 072
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    class ButtonInfo
      object Title {get;set;}
      RelayCommand Command {get;set;}

    Code xaml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <itemscontrols itemssource{binding ButtonsList}>
       <itemscontrols.itemspaneltemplate>
              <itemspaneltemplate>
                   <uniformgrid columns="5"/> <!--ou autre-->
              </itemspaneltemplate>
       </itemscontrols.itemspaneltemplate>
       <itemscontrols.itemtemplate>
            <datatemplate>
                <button content="{binding Title}" Command="{binding Command}"/>
            </datatemplate> 
        </itemscontrols.itemtemplate>
    </itemscontrols>
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  7. #7
    Expert confirmé
    Inscrit en
    Avril 2008
    Messages
    2 564
    Détails du profil
    Informations personnelles :
    Âge : 64

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 564
    Points : 4 441
    Points
    4 441
    Par défaut
    bonjour

    Comme dit pa Pol63 la meilleur facon de resoudre ton probleme est la "direction" par les les données(MVVM)...

    Comme tu le geres par code-behind.cs alors ta question
    C'est la logique du "retour à la ligne" que je n'arrive pas à transcrire dans mon code.
    Cette logique" relève de l' opération de division entière apprise au CEP2 de mon temps ( Ha ha , je divise 3 par 2 je ne peux pas ...Ecrit le Qiotient , pose le Reste et continue)....

    ton code begind .cs revu du Form :
    Code : 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
     public partial class MainWindow : Window
        {
            private List<Button> ListButtons = null;
            int count = 4; //nbre de lignes lues
            int itemsParCol = 5; //nbre de column à prevoir
            int itemsParRow = 5; //nbre de row   à prevoir
            private Random rand = new Random();
     
            public MainWindow()
            {
                InitializeComponent();
            }
            private void gridButton_Loaded(object sender, RoutedEventArgs e)
            {
     
                SetupGrid(itemsParRow,itemsParCol);
            }
            private void gridButton_SizeChanged(object sender, SizeChangedEventArgs e)
            {
                this.gridButton.Children.Clear();
     
                AddButtons(count);
            }
            private void SetupGrid(int nrow,int ncol)
            {
                for ( int i = 0; i < nrow; i++)
                {
                    this.gridButton.RowDefinitions.Add(new RowDefinition());
                }
                for (int i = 0; i < ncol; i++)
                {
                    this.gridButton.ColumnDefinitions.Add(new ColumnDefinition());
                }    
            }
            private void AddButtons(int n)
            {
                ListButtons = new List<Button>();
     
     
                for (int i = 0; i < n; i++)
                {
                    Button btn = new Button();
                    ListButtons.Add(btn);
                    ListButtons[i].Content = "Button " + i;
                    this.gridButton.Children.Add(ListButtons[i]);
     
                }
                var childCount = this.gridButton.Children.Count;
     
                // set the row and column property for each chid
                for (int i = 0; i < childCount; i++)
                {
                    var child = this.gridButton.Children[i] as FrameworkElement;
                    int reste = i % itemsParCol;
                    int quotient = i / itemsParRow;
                    Grid.SetColumn(child, reste);
                    Grid.SetRow(child, quotient);
                }
            }
     
     
        }
    code xaml du form user:
    Code XAML : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <Window x:Class="WpfGrilleButtin.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525">
        <Grid
            x:Name="gridButton"
            ShowGridLines="True"
            Loaded="gridButton_Loaded"
            SizeChanged="gridButton_SizeChanged">
     
        </Grid>
    </Window>
    bon code....

  8. #8
    Membre du Club
    Homme Profil pro
    Ingénieur
    Inscrit en
    Février 2015
    Messages
    66
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur

    Informations forums :
    Inscription : Février 2015
    Messages : 66
    Points : 63
    Points
    63
    Par défaut
    Citation Envoyé par Pol63 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    class ButtonInfo
      object Title {get;set;}
      RelayCommand Command {get;set;}

    Code xaml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <itemscontrols itemssource{binding ButtonsList}>
       <itemscontrols.itemspaneltemplate>
              <itemspaneltemplate>
                   <uniformgrid columns="5"/> <!--ou autre-->
              </itemspaneltemplate>
       </itemscontrols.itemspaneltemplate>
       <itemscontrols.itemtemplate>
            <datatemplate>
                <button content="{binding Title}" Command="{binding Command}"/>
            </datatemplate> 
        </itemscontrols.itemtemplate>
    </itemscontrols>
    Bonjour,

    Je déterre un vieux post, mais qui revient au gout du jour.
    La solution proposée ci-dessus, ainsi que MABROUKI qui disait "Comme dit pa Pol63 la meilleur facon de resoudre ton probleme est la "direction" par les les données(MVVM)..." est effectivement la meilleure manière de gérer ce problème.

    Cependant, en créant les bindings nécessaires pour la commande des boutons à travers le DataTemplate ne focntionne pas.
    Le binding Command ne fonctionne pas SEULEMENT dans le datatemplate.

    Si je crée un bouton en dehors de l'ItemControls, alors la, aucun problème pour exécuter la commande.

    Sauriez-vous d''où cela peut venir ?

    Code xaml : 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
    <Grid Background="LightSalmon">
            <Grid.RowDefinitions>
                <RowDefinition Height="*"/>
                <RowDefinition Height="*"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
     
            <ItemsControl Grid.Row="1" ItemsSource="{Binding TypeVehiculeSource}">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <UniformGrid Columns="{Binding NumberTypeVehicule}"/> 
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
     
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <!--Bouton avec Commande qui ne fonctionne pas dans l'Item Control-->
                        <Button Content="A Binder" Margin="10,10,10,10" Command="{Binding ChoixPosteCommand}"/> <!--Content="{Binding NameTypeVehicule}"-->
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
     
            <!--Bouton avec Commande qui fonctionne en dehors du Item Control-->
            <Button Content="A Binder" Margin="10,10,10,10" Command="{Binding ChoixPosteCommand}"/>
            <ContentControl Grid.Row="0" Grid.RowSpan="3" Content="{Binding SelectedViewModel}"/>  
        </Grid>

    Code : 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
    public class HomeViewModel : ObservableObject
        {
            public ICommand ChoixPosteCommand { get; set; }
     
            public ObservableCollection<string> TypeVehiculeSource { get; set; }
            public string NumberTypeVehicule { get; set; }
     
            private object _selectedViewModel;
            public object SelectedViewModel
            {
                get
                {
                    return _selectedViewModel;
                }
                set
                {
                    _selectedViewModel = value;
                    OnPropertyChanged("SelectedViewModel");
                }
            }
     
            //TODO : Afficher les noms des Types de véhicule en Binding
     
            public HomeViewModel()
            {
                ChoixPosteCommand = new RelayCommand(Open_WorkstationChoiceView);
     
                TypeVehiculeSource = new ObservableCollection<string>();
     
                TypeVehicule _typeVehicule = new TypeVehicule();
                foreach (string data in _typeVehicule.ListeTypeVehicule())
                {
                    TypeVehiculeSource.Add(data);
                }
     
                NumberTypeVehicule = TypeVehiculeSource.Count().ToString();
            }
     
            private void Open_WorkstationChoiceView(object obj)
            {
                SelectedViewModel = new WorkstationChoiceViewModel();
            }
        }

  9. #9
    Membre du Club
    Homme Profil pro
    Ingénieur
    Inscrit en
    Février 2015
    Messages
    66
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur

    Informations forums :
    Inscription : Février 2015
    Messages : 66
    Points : 63
    Points
    63
    Par défaut
    Il fallait spécifier la source de donnée car sinon la commande est cherchée dans l'ObservableCollection.

    Dans le premier cas, Command="{Binding ChoixPosteCommand}" va chercher la commande à exécuter dans la collection et non le View-Model.
    Afin d'aller chercher dans le ViewModel, j'ai dû sortir du contexte du ItemTemplate.

    Code xaml : Sélectionner tout - Visualiser dans une fenêtre à part
    Command="{Binding RelativeSource={RelativeSource AncestorType=UserControl}, Path=DataContext.ChoixPosteCommand}"

  10. #10
    Membre chevronné
    Homme Profil pro
    edi
    Inscrit en
    Juin 2007
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : edi

    Informations forums :
    Inscription : Juin 2007
    Messages : 898
    Points : 1 915
    Points
    1 915
    Par défaut
    Citation Envoyé par zeratec Voir le message
    Il fallait spécifier la source de donnée car sinon la commande est cherchée dans l'ObservableCollection.
    Dans l'item de la collection plutôt.

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

Discussions similaires

  1. Créer un nouvel objet dont on ne connait que le type
    Par NicolasJolet dans le forum C#
    Réponses: 1
    Dernier message: 08/02/2007, 09h02
  2. Créer de nouveaux objets dans une page
    Par Tronche dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 02/02/2007, 15h00
  3. Créer un formulaire d'inscription (mdp, identifiant, etc..)
    Par mirrix dans le forum Balisage (X)HTML et validation W3C
    Réponses: 3
    Dernier message: 03/01/2007, 12h00
  4. Réponses: 11
    Dernier message: 07/09/2006, 09h10
  5. Label dans /etc/fstab
    Par domileg dans le forum Administration système
    Réponses: 5
    Dernier message: 02/12/2004, 16h05

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