2010-11-08 29 views
11

Que dois-je faire d'autre pour montrer ReadAccess membres dans ce DatagridViewComboBox?Comment montrer les membres de type Enum dans un DataGridViewComboBox?

ReadDataGridViewComboBoxColumn.Items.Clear(); 
ReadDataGridViewComboBoxColumn.Items.AddRange(ReadAccess.None, ReadAccess.Allowed); 
ReadDataGridViewComboBoxColumn.ValueType = typeof(ReadAccess); 

ici est code généré concepteur-sur DataGridView:

this.rolesDataGridView.AutoGenerateColumns = false; 
this.rolesDataGridView.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { 
this.TableNameDataGridViewTextBoxColumn, 
this.ReadDataGridViewComboBoxColumn, 
this.WriteDataGridViewComboBoxColumn, 
this.ReadCodeDataGridViewComboBoxColumn, 
this.ProcessDataGridViewCheckBoxColumn, 
this.AdministrateDataGridViewCheckBoxColumn}); 
this.rolesDataGridView.DataSource = this.bsTablePermissions;

et enfin, après InitializeComponent();, je suis mise DataSource DataGridView:

this.rolesDataGridView.DataSource = this.RoleTablePermissions; // a bindingsource list
+0

Avez-vous fait 'this.Controls.Add (ReadDataGridViewComboBoxColumn)' ou similaire? –

+0

@George: oui, bien sûr ... mais quand je lance le projet, la boîte combo est gelée et je ne peux pas ouvrir sa liste ... –

+0

Y at-il plus de code pour instancier le DataGridView que juste cela? –

Répondre

21

Ceci est un problème i » J'ai rencontré plusieurs fois. Le DataGridViewComboBoxColumn ne sait pas comment concilier la différence entre la représentation de chaîne d'enum et sa valeur intégrale. Même si vous définissez ValueType sur le type de l'énumération, le DataGridView essaiera de définir la valeur de la cellule sur la valeur int sous-jacente - c'est pourquoi un FormatException sera déclenché lors de la liaison de données. La seule façon que j'ai trouvée pour surmonter ce problème (à court de sous-classer le type de cellule) est de lier le DataGridViewComboBoxColumn à une source de données qui sépare les valeurs de chaîne des valeurs entières. Vous pouvez utiliser un type anonyme à cette fin:

ReadDataGridViewComboBoxColumn.ValueType = typeof(ReadAccess); 
ReadDataGridViewComboBoxColumn.ValueMember = "Value"; 
ReadDataGridViewComboBoxColumn.DisplayMember = "Display"; 
ReadDataGridViewComboBoxColumn.DataSource = new ReadAccess[] 
    { ReadAccess.None, ReadAccess.Allowed } 
    .Select(value => new { Display=value.ToString(), Value=(int)value }) 
    .ToList(); 

De cette façon, le DataGridView sait comment relier la valeur de la cellule avec sa valeur formatée.

+0

wow ... vraiment sympa! merci beaucoup ... –

+0

@Bradley: J'ai toujours des problèmes avec ça ...La zone de liste déroulante est toujours gelée et je ne peux pas ouvrir la liste et aussi, je reçois 'FormatException' ... –

+0

@Dr TJ: Est-il possible que l'une des autres colonnes de votre' DataGridView' cause le problème, maintenant que vous avez fixé celui-ci? Vérifiez la propriété 'ColumnIndex' dans votre gestionnaire pour l'événement' DataError'. –

8

Ajouter à la réponse Smith Bradly fourni: On peut obtenir toutes les valeurs Enum (au lieu de nommer chacun individuellement) facilement en utilisant ce code:

ReadDataGridViewComboBoxColumn.DataSource = 
     new List<ReadAccess>((ReadAccess[]) Enum.GetValues(typeof(ReadAccess))) 
     .Select(value => new { Display=value.ToString(), Value=(int)value }) 
     .ToList(); 
2

Vous ne devriez pas convertir la valeur enum à l'int. Utilisez ce code si vous avez une erreur comme « valeur non valide »:

ReadDataGridViewComboBoxColumn.DataSource = new ReadAccess[] 
{ ReadAccess.None, ReadAccess.Allowed } 
.Select(value => new { Display=value.ToString(), Value=value }) 
.ToList(); 
0

Une amélioration de réponse acceptée: Il n'y a pas besoin de taper les membres de ENUM sous forme de tableau manuellement. Au lieu de cela, vous pouvez utiliser System.Enum.GetValues(typeof(ReadAccess)). En outre, au lieu de la liste de type anonyme, vous pouvez utiliser une Liste de dictionnaire (Dictionnaire est pas acceptée comme source de données):

ReadDataGridViewComboBoxColumn.DataSource= System.Enum.GetValues(typeof(ReadAccess)) 
    .Cast<Enum>.ToDictionary<string, Enum>((e) => e.ToString(), (e) => e).ToList; 

ou directement une liste KeyValuePair:

ReadDataGridViewComboBoxColumn.DataSource = System.Enum.GetValues(typeof(ReadAccess)) 
    .Cast<Enum>.Select((value) => new KeyValuePair<string, enum>(value.ToString(), (value))); 

Encore nécessaire (mais le DisplayMembre est maintenant "Key"):

ReadDataGridViewComboBoxColumn.ValueType = typeof(ReadAccess); 
ReadDataGridViewComboBoxColumn.ValueMember = "Value"; 
ReadDataGridViewComboBoxColumn.DisplayMember = "Key";