1
ModelLinkControl modelLinkControl = new ModelLinkControl(); 
modelLinkControl.bindingSourceCModels.DataSource = cModels; 
modelLinkControl.bindingSourceAModels.DataSource = aModels; 
modelLinkControl.bindingSourceModelLinks.DataSource = modelLinks; 

modelLinks는 List<MyClass>이고 3 개의 속성이 있습니다. ID, aID 및 cID. aID 및 cID는 해당 DataGridColum의 DataPropertyName에 사용됩니다. aModels 및 cModels은 두 개의 속성을 포함하는 List<AnotherClass>입니다. ID 및 이름은 해당 ComboBoxValueMember = "ID"DisplayMember = "Name"에 사용합니다.DataGridViewComboBox 및 ValueMember를 사용하려고하면 System.ArgumentException이 발생합니다.

위의 스 니펫의 마지막 줄에 있습니다.

System.ArgumentException occurred 
    Message=Field called ID does not exist. 
    Source=System.Windows.Forms 
    StackTrace: 
     at System.Windows.Forms.DataGridViewComboBoxCell.InitializeValueMemberPropertyDescriptor(String valueMember) 
     at System.Windows.Forms.DataGridViewComboBoxCell.OnDataGridViewChanged() 
     at System.Windows.Forms.DataGridViewRowCollection.AddInternal(DataGridViewRow dataGridViewRow) 
     at System.Windows.Forms.DataGridView.RefreshRows(Boolean scrollIntoView) 
     at System.Windows.Forms.DataGridView.RefreshColumnsAndRows() 
     at System.Windows.Forms.DataGridView.DataGridViewDataConnection.ProcessListChanged(ListChangedEventArgs e) 
     at System.Windows.Forms.DataGridView.DataGridViewDataConnection.currencyManager_ListChanged(Object sender, ListChangedEventArgs e) 
     at System.Windows.Forms.CurrencyManager.OnListChanged(ListChangedEventArgs e) 
     at System.Windows.Forms.CurrencyManager.List_ListChanged(Object sender, ListChangedEventArgs e) 
     at System.Windows.Forms.BindingSource.OnListChanged(ListChangedEventArgs e) 
     at System.Windows.Forms.BindingSource.ResetBindings(Boolean metadataChanged) 
     at System.Windows.Forms.BindingSource.SetList(IList list, Boolean metaDataChanged, Boolean applySortAndFilter) 
     at System.Windows.Forms.BindingSource.ResetList() 
     at System.Windows.Forms.BindingSource.set_DataSource(Object value) 
    InnerException: 

모든 입력란, 클래스 및 속성의 철자를 검사했습니다. 디자이너의 모든 열을 제거하고 다시 추가하여 모든 철자를주의 깊게 확인했습니다. modelLinks의 ID가 aModels 및 cModels에 존재합니다. 또한 3 개의 목록 모두에서 List<>에서 BindingList<>으로 변경해 보았습니다. 그리고 난 그냥 같은 오류가 계속.

ValueMember = "ID"을 제거하면 AnotherClassGuid와 일치하지 않으므로 다른 오류가 발생합니다. 나는 다음 시도 모르는

은 ...

디자이너가 생성 :

// 
// dataGridViewModels 
// 
this.dataGridViewModels.AllowUserToAddRows = false; 
this.dataGridViewModels.AllowUserToDeleteRows = false; 
this.dataGridViewModels.AutoGenerateColumns = false; 
this.dataGridViewModels.CellBorderStyle = System.Windows.Forms.DataGridViewCellBorderStyle.None; 
this.dataGridViewModels.ColumnHeadersBorderStyle = System.Windows.Forms.DataGridViewHeaderBorderStyle.None; 
this.dataGridViewModels.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; 
this.dataGridViewModels.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { 
this.ColumnC, 
this.ColumnA}); 
this.dataGridViewModels.DataSource = this.bindingSourceModelLinks; 
this.dataGridViewModels.Dock = System.Windows.Forms.DockStyle.Fill; 
this.dataGridViewModels.Location = new System.Drawing.Point(0, 0); 
this.dataGridViewModels.Name = "dataGridViewModels"; 
this.dataGridViewModels.RowHeadersVisible = false; 
this.dataGridViewModels.Size = new System.Drawing.Size(794, 445); 
this.dataGridViewModels.TabIndex = 0; 
// 
// ColumnC 
// 
this.ColumnC.DataPropertyName = "cID"; 
this.ColumnC.DataSource = this.bindingSourceCModels; 
this.ColumnC.HeaderText = "cModel"; 
this.ColumnC.Name = "ColumnC"; 
this.ColumnC.DisplayMember = "Name"; 
this.ColumnC.ValueMember = "ID"; 
// 
// ColumnA 
// 
this.ColumnA.DataPropertyName = "aID"; 
this.ColumnA.DataSource = this.bindingSourceAModels; 
this.ColumnA.HeaderText = "aModel"; 
this.ColumnA.Name = "ColumnA"; 
this.ColumnA.DisplayMember = "Name"; 
this.ColumnA.ValueMember = "ID"; 

답변

1

나는 지금 막이 :

Form1.cs를

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 

namespace TestDataGridView 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 

      this.PopulateDataGrid(); 
     } 

     private void PopulateDataGrid() 
     { 
      List<BindID> bindList = new List<BindID>(); 
      List<ClassA> aList = new List<ClassA>(); 
      List<ClassB> bList = new List<ClassB>(); 

      for (int i = 0; i < 10; i++) 
      { 
       ClassA newClassA = new ClassA() { ID = Guid.NewGuid(), Name = i.ToString() }; 
       ClassB newClassB = new ClassB() { ID = Guid.NewGuid(), Name = i.ToString() }; 
       BindID newBindID = new BindID() { ID = Guid.NewGuid(), AID = newClassA.ID, BID = newClassB.ID }; 

       bList.Add(newClassB); 
       aList.Add(newClassA); 
       bindList.Add(newBindID); 
      } 

      bindingSourceA.DataSource = aList; 
      ColumnA.ValueMember = "ID"; 
      ColumnA.DisplayMember = "Name"; 

      bindingSourceB.DataSource = bList; 
      ColumnB.ValueMember = "ID"; 
      ColumnB.DisplayMember = "Name"; 

      bindingSourceBindID.DataSource = bindList; 
     } 
    } 

    public class BindID 
    { 
     public Guid ID { get; set; } 
     public Guid AID { get; set; } 
     public Guid BID { get; set; } 
    } 
    public class ClassA 
    { 
     public Guid ID { get; set; } 
     public string Name { get; set; } 
    } 
    public class ClassB 
    { 
     public Guid ID { get; set; } 
     public string Name { get; set; } 
    } 
} 

를 Form1 .Designer.cs

namespace TestDataGridView 
{ 
    partial class Form1 
    { 
     /// <summary> 
     /// Required designer variable. 
     /// </summary> 
     private System.ComponentModel.IContainer components = null; 

     /// <summary> 
     /// Clean up any resources being used. 
     /// </summary> 
     /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> 
     protected override void Dispose(bool disposing) 
     { 
      if (disposing && (components != null)) 
      { 
       components.Dispose(); 
      } 
      base.Dispose(disposing); 
     } 

     #region Windows Form Designer generated code 

     /// <summary> 
     /// Required method for Designer support - do not modify 
     /// the contents of this method with the code editor. 
     /// </summary> 
     private void InitializeComponent() 
     { 
      this.components = new System.ComponentModel.Container(); 
      this.dataGridView1 = new System.Windows.Forms.DataGridView(); 
      this.bindingSourceBindID = new System.Windows.Forms.BindingSource(this.components); 
      this.bindingSourceA = new System.Windows.Forms.BindingSource(this.components); 
      this.bindingSourceB = new System.Windows.Forms.BindingSource(this.components); 
      this.ColumnA = new System.Windows.Forms.DataGridViewComboBoxColumn(); 
      this.ColumnB = new System.Windows.Forms.DataGridViewComboBoxColumn(); 
      ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit(); 
      ((System.ComponentModel.ISupportInitialize)(this.bindingSourceBindID)).BeginInit(); 
      ((System.ComponentModel.ISupportInitialize)(this.bindingSourceA)).BeginInit(); 
      ((System.ComponentModel.ISupportInitialize)(this.bindingSourceB)).BeginInit(); 
      this.SuspendLayout(); 
      // 
      // dataGridView1 
      // 
      this.dataGridView1.AutoGenerateColumns = false; 
      this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; 
      this.dataGridView1.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { 
      this.ColumnA, 
      this.ColumnB}); 
      this.dataGridView1.DataSource = this.bindingSourceBindID; 
      this.dataGridView1.Dock = System.Windows.Forms.DockStyle.Fill; 
      this.dataGridView1.Location = new System.Drawing.Point(0, 0); 
      this.dataGridView1.Name = "dataGridView1"; 
      this.dataGridView1.Size = new System.Drawing.Size(709, 407); 
      this.dataGridView1.TabIndex = 0; 
      // 
      // ColumnA 
      // 
      this.ColumnA.DataPropertyName = "AID"; 
      this.ColumnA.DataSource = this.bindingSourceA; 
      this.ColumnA.HeaderText = "ColumnA"; 
      this.ColumnA.Name = "ColumnA"; 
      // 
      // ColumnB 
      // 
      this.ColumnB.DataPropertyName = "BID"; 
      this.ColumnB.DataSource = this.bindingSourceB; 
      this.ColumnB.HeaderText = "ColumnB"; 
      this.ColumnB.Name = "ColumnB"; 
      // 
      // Form1 
      // 
      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 
      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 
      this.ClientSize = new System.Drawing.Size(709, 407); 
      this.Controls.Add(this.dataGridView1); 
      this.Name = "Form1"; 
      this.Text = "Form1"; 
      ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit(); 
      ((System.ComponentModel.ISupportInitialize)(this.bindingSourceBindID)).EndInit(); 
      ((System.ComponentModel.ISupportInitialize)(this.bindingSourceA)).EndInit(); 
      ((System.ComponentModel.ISupportInitialize)(this.bindingSourceB)).EndInit(); 
      this.ResumeLayout(false); 

     } 

     #endregion 

     private System.Windows.Forms.DataGridView dataGridView1; 
     private System.Windows.Forms.BindingSource bindingSourceBindID; 
     private System.Windows.Forms.BindingSource bindingSourceA; 
     private System.Windows.Forms.BindingSource bindingSourceB; 
     private System.Windows.Forms.DataGridViewComboBoxColumn ColumnA; 
     private System.Windows.Forms.DataGridViewComboBoxColumn ColumnB; 
    } 
} 

새로운 별도의 프로젝트에서는 매력처럼 작동합니다. 적어도 내가 잘못한 일을하고 있으며, 내가 위에 제시하지 않은 프로젝트의 다른 것과 관련 될 수 있다는 것을 알 수 있습니다. DataGrid를 채우는 방식과 아무 관련이 없습니다.

나는이 질문을 끝내고 사냥을 계속할 것이다.

업데이트 (솔루션) : [BrowsableAttribute(false)]은 악의입니다! : P 그걸 다시 볼 때 좀 더 분명해. PropertyGrid에 클래스를 표시 할 때 다른 컨트롤에도 영향을 미칠 것으로 생각하지 않아 ID를 숨기려고했습니다. 실제로 더 많은 특성을 연구해야합니다 ...

+0

그냥 BrowsableAttribute (false)를 직접 실행했습니다. 좋은 캐치. – jcox

관련 문제