2009-04-20 7 views
4

コントロールにDataSourceプロパティを割り当てるときに問題があります。私のDataSourceDataTableDefaultViewであり、期待通りにDataGridViewに列が自動的に作成され、DataTableに割り当てられた列と一致します。DataGridViewが繰り返し列を再作成する

次に起こるのは、列が自動的に削除され、さらに2回、DataGridViewによって再作成されたようです。なぜこれが起こるのだろうか?フォームのコンストラクタで

//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. 

編集:追加されました(たぶん)自己完結型の例。イベントハンドラにブレークポイントを設定した場合、「追加済み」に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

イベントハンドラでブレークポイントを設定すると、「追加」と「削除」が4回1回発生します。DataTableには2列内で削除するカラムを決して尋ねることはありません。 – xyz

答えて

1

多くの手品を取った後、これは行く方法のようです。フォームのShownイベントハンドラで

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

の列ごとに1回発射される ColumnAddedイベントの望ましい結果を与える
dgv.AutoGenerateColumns = true; 

、およびColumnRemovedフォームのLoadイベントハンドラで

イベントはまったく解雇されません。 (LoadイベントハンドラにAutoGenerateColumns = trueが設定されている場合は、この煩わしいAdd-Remove-Addダンスを行います)

1

。列がすでに設計時に存在するときのDito。

グリッドが空で、デザイナーでDataSourceプロパティがクリアされていることを確認してください。

追加:

私は、サンプルコードを実行し、それを確認することができますが、通常のForm_Loadイベントに、コンストラクタからコードを移動することによって、(半体)狂気を減らすことができます。とにかく、それは正しい方法です。私は非常に多くの人々がctorと負荷を混乱させるのを見ています。

しかし、それでも1列に2つの追加アクションと1つの削除アクションがありますが、私はそれをいくつかのDataGrid非効率性に登録する必要があると思います。 (DataSource.setのどこか())

追加2:

はどうやらAutoGenerateColumnsはデフォルトではtrueで、プロパティウィンドウから直接設定可能ではありません。私は、デザイン時にデータソースを設定(そして後にクリア)することでそれをクリアしました。そして、AutoGenerateColumnsプロパティをクリアすると、

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

2つのAddイベントだけが出力されます。

+0

これらはどちらも私が知っている限りです。時間があれば投稿したコードを試してください:-) – xyz

+0

ありがとう。私はあなたの2番目の追加を理解していません。したがって、デフォルトで.AutoGenerateColumnsは 'true'で、.DataSourceは 'null'です - 私は開始点として望んでいる値ではありません。 AGCをtrueに設定すると(それが既にtrueの場合)、デザイナで手動でデータソースを追加/削除すると何が達成されますか? – xyz

+0

ああ、私は順番に行うことによって動作しています:AGC = false、DataSourceを割り当て、AGC = true :-) – xyz

2

IのDataTableの内容を表示するためのDataGridViewを使用してアプリを持っていますが、私はこのようにそれらをリンク:

dataGridView.DataSource = dataTable; 

あなたはこれを試すことができますか?

EDIT:

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

ないのはなぜこれはしかし違いになるだろうしてください:

私はまた、コードを自動生成して、次のしています。

+0

同じことが起こります。私は何か根本的に間違っているか、ここで何か不思議なことが起きています。質問の例にはほとんどコードがありません。それでも起こります。 – xyz

1

数ヶ月前、私たちはフィルタリング機能を内蔵したGridコントロールを構築していました(Excelに似ています)。最初は、datagridviewを使用して、その周りに構築しました。今問題になっているこの問題は、私たちの一番の大きな棘でした!私たちは下にDGVを使用していたので、私たちがやる必要のあるさまざまなことを引き起こすためにそのイベントに突入していたので、それは絶対的な悪夢でした。 DGVは偉大なコントロールですが、カバーの下でそれはいくつかの騒々しいsh **を行います!その日の終わりの最善の回避策は、自動的に列を自動生成することでした。そうです、それは痛みでしたが、少なくとも私たちは完全に支配していました。

私たちの最終版では、私たちはすべて一緒に掻き集めて、継承ルートに行きました。私たちはDGVから継承し、私たちの生活をもっと楽にしました。今、あなたがここで達成しようとしていることは分かりませんが、自分のグリッドを構築している場合は、まず相続を試してみてください!あなたの質問に対する答えは、間違ったことはしていません。 datagridviewはちょうどそのようなキキーです。あなたがDGVの周りにコントロールを構築しておらず、それらのイベントだけが必要な場合は、追加/削除された列から離れるようにしてください。代わりにbindingcompletedを使用できるかどうかを確認してください。

+0

アドバイスありがとうございます。私はそれが働いている(上記を参照してください)にcoaxedされていると思うが、私はそれが少し乾杯できることを覚えておくよ! – xyz

1

私は解決策を得ました!フォームまたはユーザーコントロールを選択し、Localizableプロパティの値をtrueに変更します。 resxファイルを編集し、UserAddedColumnエントリを抑制します。次に、あなたのデータグリッドを選択し、 "列の変更"を選択します。自動的に追加されたすべての列を非表示にします。 Localizableの値をfalseにリセットします。そうすることで、自動的に追加された列はグリッドに戻ってきませんでした。

おそらくフォーム/ユーザーコントロールを保存し、各操作の間にデザインタブを閉じる必要があります。

関連する問題