2016-08-31 4 views
0

하나의 열이 ComboBox 인 DataTable에 바인딩 된 DataGridView를 만들려고합니다. 코드가 실행되지만 바인딩 후 데이터가 바인딩되지 않은 경우 다음 오류가 발생합니다. System.ArgumentException : DataGridViewComboBoxCell 값이 올바르지 않습니다. DataGridView를 열 중 하나에서 ComboBox가있는 DataTable에 DataGridView를 바인딩하지 않습니다.

이 소스의로 열거 (이름 structureType)를 사용하는 DataGridViewComboBoxColumn이다 : 나는 DataTable을 사용하지 않고있는 DataGridView를 채울 때

// ColumnStructure 
// 
this.ColumnStructure.ValueType = typeof(structureType); 
this.ColumnStructure.DataSource = Enum.GetValues(typeof(structureType)); 
this.ColumnStructure.HeaderText = "Structure"; 
this.ColumnStructure.Name = "ColumnStructure"; 
this.ColumnStructure.DataPropertyName = "Structure"; 
// 

, 그것은 잘 작동 :

structureType? structure = GetStructure(part); 
dgvObjectTypes.Rows.Add(name, type, structure, count); 

이제 DataTable을 대신 사용하고 싶지만 제대로 작동하지 않습니다. DataTable은 다음과 같이 생성됩니다.

DataTable table = new DataTable(); 
table.Columns.Add("Name", typeof(string)); 
table.Columns.Add("Type", typeof(string)); 
table.Columns.Add("Structure", typeof(DataGridViewComboBoxCell)); 
table.Columns.Add("Count", typeof(int)); 

다른 열은 훌륭하게 작동하지만 "구조"열은 작동하지 않습니다. 그 후

var cb = new DataGridViewComboBoxCell(); 
cb.ValueType = typeof(structureType); 
cb.DataSource = Enum.GetValues(typeof(structureType)); 
cb.Value = (structureType)structure; 

난 그냥 테이블에 대한 행을 작성하고 DataGridView에 대한 데이터 소스로 테이블을 설정 : 내가 읽은

table.Rows.Add(name, type, cb, count); 
dgv.DataSource = table; 

여기에 내가 콤보를 만들려고 한 방법 콤보 상자에서 열거 형을 사용하면 문제가 발생한다는 게시물이 많이 있습니다 (예 : DataGridView linked to DataTable with Combobox column based on enum).하지만 여기서는 그렇지 않습니다. 명시 적으로 형식화 된 문자열 배열을 사용하려했지만 여전히 동일한 오류가 발생했습니다. DataGridViewComboBoxCell에 문제가 있다고 생각합니다.

무엇이 문제 일 수 있습니까?

답변

3

누락 된 단계는 CBO의 이름과 값을 제공하는 것 같습니다. DataTable은 값을 저장할 수 있으며 DGV는 관련 이름을 표시 할 수 있지만 번역을 제공해야합니다.

private enum structureType 
{ None, Circle, Square, Pyramid} 
... 

dtStruct = new DataTable(); 
dtStruct.Columns.Add("Name", typeof(string)); 
dtStruct.Columns.Add("Type", typeof(string)); 
dtStruct.Columns.Add("Structure", typeof(structureType)); 
dtStruct.Columns.Add("Count", typeof(int)); 

// autogen columns == true 
dgv2.DataSource = dtStruct; 

// create DataSource as list of Name-Value pairs from enum 
var cboSrc = Enum.GetNames(typeof(structureType)). 
        Select(x => new {Name = x, 
             Value = (int)Enum.Parse(typeof(structureType),x) 
             } 
          ).ToList(); 

// replace auto Text col with CBO col 
DataGridViewComboBoxColumn cb = new DataGridViewComboBoxColumn(); 
cb.ValueType = typeof(structureType); 
cb.DataSource = cboSrc; 
cb.DisplayMember = "Name";   // important 
cb.ValueMember = "Value";   // important 
cb.HeaderText = "Structure"; 
cb.DataPropertyName = "Structure"; // where to store the value 

dgv2.Columns.Remove(dgv2.Columns[2]); // remove txt col 
dgv2.Columns.Add(cb); 
cb.DisplayIndex = 2; 

// add data 
dtStruct.Rows.Add("Ziggy", "Foo", structureType.Circle, 6); 

첫 번째 부분은 DataTable 생성 구조 칼럼 타입 structureType (또는 종종 int)되어 있습니다. DataTable은 데이터를 저장하며, DataGridViewComboBoxCell 요소는 저장하지 않습니다. 데이터베이스에서 데이터를 가져 오는 경우 일 수 있습니다. structureType은 알려진 유형이 아니기 때문입니다.

DataSource은 열거 형 이름과 값으로 생성됩니다. 이렇게하면 컨트롤에 이름을 표시하고 DataTable에 값을 저장할 수 있습니다.

DGV가 자동 생성 열로 설정된 경우 기본값 TextBoxColumnComboBoxColumn으로 바꿔야합니다. 이것은 DataSource이 설정되었지만 데이터가 추가되기 전에 수행됩니다. DB에서 데이터를 가져올 때 (일반적으로 빈 테이블 유형이없는 경우) ColumnAdded 이벤트를 사용하여 한 열을 다른 열로 바꿀 수 있습니다. > 이름 변환과 DataTable에서 선택한 값을 저장할 위치를 DataPropertyName 그래서 그것이 알고 -

CBO의 열을 추가 중요한 것은 값 <을 제공하기 위해 ValueMemberDsiplayMember 속성을 설정하는 것입니다.

enter image description here

+0

고마워요! 나는 이미 희망을 잃었습니다. 추가 질문 : 'structureType?'이 null이면 combobox show를 비어있는 방법으로 설정할 수 있습니까? 멋지 겠지만 열거 형에 "None"을 추가하면됩니다. – JayByte

+0

'없음'을 추가하는 것이 가장 간단합니다. – Plutonix

관련 문제