2010-11-08 6 views
11

Was muss ich noch tun, um ReadAccess Enum-Mitglieder in dieser DatagridViewComboBox anzuzeigen?Wie zeigen Enum-Typ-Mitglieder in einer DataGridViewComboBox?

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

hier ist Designer generierten Codes über 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;

und schließlich in nach InitializeComponent();, ich bin Datagridview Datasource-Einstellung:

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

Haben Sie 'this.Controls.Add (ReadDataGridViewComboBoxColumn)' oder ähnliches? –

+0

@George: Ja, sicher ... aber wenn ich das Projekt ausführen, ist das Kombinationsfeld eingefroren und ich kann seine Liste nicht öffnen ... –

+0

Gibt es mehr Code, um das DataGridView als nur das zu instanziieren? –

Antwort

21

Dies ist ein Problem i‘ Ich bin oft begegnet. Die DataGridViewComboBoxColumn kann nicht den Unterschied zwischen der String-Darstellung der Enumeration und seinem Integralwert abgleichen. Obwohl Sie ValueType auf den Typ der Enumeration festlegen, wird DataGridView versuchen, den Wert der Zelle auf den zugrunde liegenden Wert int festzulegen - daher wird beim Datenbonding eine FormatException ausgelöst.

Die einzige Möglichkeit, dieses Problem zu lösen (keine Unterklasse des Zelltyps), besteht darin, das DataGridViewComboBoxColumn an eine Datenquelle zu binden, die die Zeichenfolgenwerte von den ganzzahligen Werten trennt. Sie können einen anonymen Typ für diesen Zweck verwenden:

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(); 

diese Weise die DataGridView weiß, wie die Zelle Wert mit seinem formatiert Wert zu beziehen.

+0

wow ... wirklich nett! Vielen Dank ... –

+0

@Bradley: Ich habe immer noch Probleme mit diesem ...Die Combo-Box ist immer noch eingefroren und ich kann die Liste nicht öffnen und auch, bekomme ich 'FormatException' ... –

+0

@Dr TJ: Ist es möglich, dass eine der anderen Spalten in Ihrem' DataGridView' das Problem jetzt verursacht dass du das repariert hast? Überprüfen Sie die Eigenschaft "ColumnIndex" in Ihrem Handler auf das Ereignis "DataError". –

8

Zusätzlich zu der Antwort Bradley Smith zur Verfügung gestellt: Man kann all Enum-Wert erhalten (statt jeweils einzeln zu benennen) leicht mit diesem Code:

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

Sie sollten nicht Enum-Wert in den int konvertieren. Verwenden Sie diesen Code, wenn Sie einen Fehler wie „ungültiger Wert“ haben:

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

Eine Verbesserung akzeptierte Antwort: Es gibt keine Notwendigkeit, manuell Enum-Mitglieder als Array einzugeben. Stattdessen können Sie System.Enum.GetValues(typeof(ReadAccess)) verwenden. Auch anstelle von anonymen Typ-Liste können Sie eine Liste von Wörterbuch verwenden (Dictionary nicht als Datenquelle akzeptiert):

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

oder direkt eine KeyValuePair Liste:

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

Noch erforderlich (aber DisplayMember ist jetzt "Key"):

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