2010-11-08 18 views
11

¿Qué más tengo que hacer para mostrar ReadAccess enumeradores en este DatagridViewComboBox?¿Cómo mostrar los miembros del tipo Enum en un DataGridViewComboBox?

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

aquí es códigos del diseñador-generado alrededor de 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;

y finalmente, después de InitializeComponent();, Soy la creación de DataGridView DataSource:

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

¿Has hecho 'this.Controls.Add (ReadDataGridViewComboBoxColumn)' o similar? –

+0

@George: sí, claro ... pero cuando ejecuto el proyecto, el cuadro combinado está congelado y no puedo abrir su lista ... –

+0

¿Hay más código para instanciar DataGridView que solo esto? –

Respuesta

21

Este es un problema i' he venido muchas veces El DataGridViewComboBoxColumn no sabe cómo conciliar la diferencia entre la representación de cadena de la enumeración y su valor integral. Aunque establezca ValueType en el tipo de enumeración, DataGridView intentará establecer el valor de la celda en el valor int subyacente; esta es la razón por la cual se generará un FormatException durante la vinculación de datos.

La única forma que he encontrado para solucionar este problema (salvo la subclasificación del tipo de celda) es vincular DataGridViewComboBoxColumn a una fuente de datos que separa los valores de cadena de los valores enteros. Se puede utilizar un tipo anónimo para este propósito:

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 esta manera, el DataGridView sabe cómo relacionar el valor de la celda con su valor con formato.

+0

guau ... ¡muy bien! muchas gracias ... –

+0

@radley: todavía tengo problemas con esto ...El cuadro combinado todavía está congelado y no puedo abrir la lista y, además, recibo 'FormatException' ... –

+0

@Dr TJ: ¿Es posible que una de las otras columnas en su' DataGridView' esté causando el problema, ahora que has arreglado este? Compruebe la propiedad 'ColumnIndex' en su controlador para el evento' DataError'. –

8

Agregando a la respuesta proporcionada Bradley Smith: Uno puede obtener todos los valores de enumeración (en lugar de nombrar a cada uno individualmente) fácilmente usando este código:

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

No debe convertir el valor de enumeración a la int. Utilice este código si usted tiene un error como "valor no válido":

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

una mejora de respuesta aceptada: No hay necesidad de escribir los miembros de enumeración como un array de forma manual. En su lugar, puede usar System.Enum.GetValues(typeof(ReadAccess)). Además, en lugar de la lista de tipo anónimo, se puede utilizar una lista de Diccionario (Diccionario no se acepta como fuente de datos):

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

o directamente una lista KeyValuePair:

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

Todavía es necesario (pero DisplayMember ahora es "clave"):

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