2009-04-20 4 views
4

DataGridView 컨트롤에 DataSource 속성을 할당 할 때 문제가 있습니다. 내 DataSourceDataTableDefaultView이고 예상 한대로 DataGridView에 열이 지정되면 DataTable의 열과 일치하도록 열이 자동으로 만들어집니다.DataGridView가 반복적으로 열을 다시 작성합니다.

다음에 발생하는 것은 열이 자동으로 제거되고 DataGridView에 의해 추가로 2 번 재현되는 것입니다. 왜 이런 일이 일어 났을까요? 폼의 생성자에서

:

//A DataTable is created with 5 columns 
//The DataTable is populated with some rows. 

myDgv.AutoGenerateColumns = true; 
myDgv.DataSource = myDataTable.DefaultView; 
// myDgv.ColumnAdded event is fired 5 times. 
// WHY: myDgv.ColumnRemoved event is fired 5 times. 
// WHY: myDgv.ColumnAdded event is fired 5 times. 
// WHY: myDgv.ColumnRemoved event is fired 5 times. 
// WHY: myDgv.ColumnAdded event is fired 5 times. 

편집 : A (희망) 자체가 예를 들어 추가되었습니다. 이벤트 처리기에 중단 점을 설정하면 '추가됨'이 6 번, '제거됨'이 4 번 눌려집니다. DataTable에는 2 개의 열이 포함되어 있으며 코드에서 제거 할 열을 묻지 않습니다. myDgv.DataSource이 alreadys 추가의 적어도 일부/제거 작업을 설명 할 무언가로 설정되어있는 경우

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 asdasdgf 
{ 
    public class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 

      DataTable dt = new DataTable(); 
      dt.Columns.Add("Col1", typeof(int)); 
      dt.Columns.Add("Col2", typeof(string)); 

      foreach (int i in Enumerable.Range(0, 10)) 
      { 
       var row = dt.NewRow(); 
       row["Col1"] = i; 
       row["Col2"] = "stackoverflow"; 
       dt.Rows.Add(row); 
      } 

      dataGridView1.ColumnAdded += new DataGridViewColumnEventHandler(dataGridView1_ColumnAdded); 
      dataGridView1.ColumnRemoved += new DataGridViewColumnEventHandler(dataGridView1_ColumnRemoved); 

      dataGridView1.DataSource = dt.DefaultView; 
     } 

     void dataGridView1_ColumnRemoved(object sender, DataGridViewColumnEventArgs e) 
     { 
      // Break here 
     } 

     void dataGridView1_ColumnAdded(object sender, DataGridViewColumnEventArgs e) 
     { 
      // Break here 
     } 

     // Form1.Designer.cs contents: 
     #region Windows Form Designer generated code 
     private System.ComponentModel.IContainer components = null; 
     private System.Windows.Forms.DataGridView dataGridView1; 

     protected override void Dispose(bool disposing) 
     { 
      if (disposing && (components != null)) 
      { 
       components.Dispose(); 
      } 
      base.Dispose(disposing); 
     } 



     /// <summary> 
     /// Required method for Designer support - do not modify 
     /// the contents of this method with the code editor. 
     /// </summary> 
     private void InitializeComponent() 
     { 
      this.dataGridView1 = new System.Windows.Forms.DataGridView(); 
      ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit(); 
      this.SuspendLayout(); 
      // 
      // dataGridView1 
      // 
      this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; 
      this.dataGridView1.Location = new System.Drawing.Point(12, 41); 
      this.dataGridView1.Name = "dataGridView1"; 
      this.dataGridView1.Size = new System.Drawing.Size(240, 150); 
      this.dataGridView1.TabIndex = 0; 
      // 
      // Form1 
      // 
      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 
      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 
      this.ClientSize = new System.Drawing.Size(284, 264); 
      this.Controls.Add(this.dataGridView1); 
      this.Name = "Form1"; 
      this.Text = "Form1"; 
      ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit(); 
      this.ResumeLayout(false); 

     } 

     #endregion 
    } 
} 
+1

대신 BindingSource를 사용하면 어떻게됩니까? –

+0

같은 일이 발생합니다 :-( – xyz

+0

자발적으로 포함 된 예제를 추가했습니다. 이벤트 처리기에 중단 점을 설정하면 '추가됨'이 6 번, '제거됨'이 4 번 발생합니다 .DataTable에는 2 열 및 결코 내 코드에서 제거 할 수있는 열을 요청하지 마십시오. – xyz

답변

1

많은 재미를봤을 때, 이것이 갈 길이 된 것 같습니다. 양식의 Shown 이벤트 핸들러에서

dgv.AutoGenerateColumns = false; 
dgv.DataSource = myDataSource; 

: 양식의 Load 이벤트 핸들러에서

dgv.AutoGenerateColumns = true; 

ColumnAdded 이벤트의 원하는 결과를주기는 각 열에 대해 한 번 발사하고 ColumnRemoved되고 이벤트가 전혀 실행되지 않습니다. (Load 이벤트 핸들러에 AutoGenerateColumns = true가 설정된 경우이 추가 작업은 Add-Remove-Add 댄스를 수행합니다.)

1

. Dito 열이 이미 디자인 타임에있는 경우.

그리드가 비어 있고 디자이너에서 DataSource 속성이 지워 졌는지 확인하십시오.

추가 :

나는 샘플 코드를 실행하고 확인 할 수 있지만 정상적인 Form_Load 이벤트 생성자의 코드를 이동하여 (이등분) 광기를 줄일 수 있습니다. 그것은 적절한 방법입니다. 여하튼, 너무 많은 사람들이 ctor와 Load를 혼란스럽게 보았습니다.

하지만 여전히 열당 2 개의 추가 및 1 개의 제거 동작이 있습니다. 데이터 그 룹의 비효율적 인 부분을 구독해야 할 것 같습니다. (어딘가에 DataSource.set에서())이 추가

:

분명히 AutoGenerateColumns은 기본적으로 사실과 속성 창에서 직접 설정할 수없는. 디자인 타임에 데이터 소스를 설정하고 나중에 지우는 방법으로이를 지웠다. 그런 다음 지워진 AutoGenerateColumns 속성을 사용하면

dataGridView1.AutoGenerateColumns = true; 
dataGridView1.DataSource = dt.DefaultView; 

두 개의 Add 이벤트 만 생성됩니다.

+0

그 두 경우 모두 내가 알고있는 경우입니다. 시간이 있으면 게시 한 코드 시도하십시오 :-) – xyz

+0

도와 주셔서 감사합니다 . 너의 두번째 추가를 이해하지 못한다. 따라서, 기본적으로 .AutoGenerateColumns는 'true'이고 .DataSource는 'null'입니다. - 시작점으로 원하는 값이 아닌가? AGC를 true로 설정하고 (이미 true 일 때) 디자이너가 수동으로 DataSource를 추가/제거하는 것은 무엇입니까? – xyz

+0

아아, 순서대로 처리하면 작동합니다. AGC = false, 데이터 소스 할당, AGC = true :-) – xyz

2

I DataTable을의 내용을 표시하는 DataGridView를 사용하는 응용 프로그램을 가지고,하지만이처럼 연결 :

dataGridView.DataSource = dataTable; 

당신이 시도 할 수 있습니까?

편집 :

this.dataGridView.EditMode = System.Windows.Forms.DataGridViewEditMode.EditProgrammatically; 

확실하지 않음이 비록 차이를 만들 이유 : 나는 자동으로 다음은 코드를 생성 또한 한

.

+0

같은 일이 발생합니다. 내가 근본적으로 잘못된 것을하고 있거나 뭔가 이상한 일이 일어나고 있습니다. 질문에 예제에있는 코드가 거의없고 여전히 발생합니다. – xyz

1

몇 달 전에 직장에서 필터링 기능이 내장 된 Grid 컨트롤을 구축했습니다 (Excel과 유사). 처음에는 datagridview를 사용했고 그 주위에 빌드했습니다. 이 문제는 지금 우리가 염색하고있는 가장 큰 가시였습니다! 우리가 밑에있는 DGV를 사용하고 있었고, 우리가 할 필요가있는 다양한 것들을 트리거하기 위해 이벤트에 연결했기 때문에 그것은 절대적인 악몽이었습니다. DGV는 훌륭한 컨트롤이지만, 커버 아래에서 그것은 불안정한 일을합니다 ** !! 최후의 해결책은 열을 자동으로 생성하는 것입니다. 그래, 고통 스러웠지 만 적어도 우리는 완전히 통제 할 수 있었다.

최종 버전에서는 결국 모두 긁어 모으고 상속 경로를 따라갔습니다. 우리는 DGV에서 물려 받았고 우리 삶을 더 쉽게 만들었습니다. 자, 여기서 무엇을하려고하는지 잘 모르겠지만 자신 만의 그리드를 만드는 경우 상속을 먼저 ​​시도하십시오! 당신의 질문에 대한 대답은, 당신은 아무 잘못도 없습니다. datagridview는 그저 그런 괴짜 야. DGV 주변에 컨트롤을 구축하지 않고 이러한 이벤트가 필요하다면 열 추가/제거에서 벗어나려고합니다. 대신 bindingcompleted를 대신 사용할 수 있는지 확인하십시오.

+0

조언을 주셔서 감사합니다. 내 생각에 그것은 작업에 압박감을 느꼈다. (위 참조), 나는 약간의 건초 더미 일 수 있다는 것을 명심한다! – xyz

1

솔루션을 얻었습니다! 양식 또는 사용자 정의 컨트롤을 선택하고 Localizable 속성 값을 true로 변경합니다. resx 파일을 편집하고 UserAddedColumn 항목을 표시하지 않습니다. 그런 다음 데이터 격자를 선택하고 "열 수정"을 선택하십시오. 자동으로 추가 된 모든 열을 숨기십시오. Localizable 값을 false로 재설정합니다. 이렇게하면 자동으로 추가 된 열이 그리드에 다시 나타나지 않습니다.

어쩌면 양식/사용자 컨트롤을 저장하고 각 작업 사이에 디자인 탭을 닫아야 할 수도 있습니다.

관련 문제