2009-05-20 10 views
8

データソースにバインドされたComboBoxがあります。特定の条件に基づいてコンボボックスにアイテムを動的に追加したい。それでは、私がやったことは、新しいリストにオプションを追加して、そのようなコンボボックスのデータソースを変更です:ComboBox items.countがデータソースと一致しません(C#)

cbo.DataSource = null; 
cbo.DataSource = cbos; 
cbo.DisplayMember = "Title"; 
cbo.ValueMember = "Value"; 

その後、私はcbo.Items.Countをチェックし、それがインクリメントされていない - それは等しくありませんデータソースの数。私はここで何ができますか?これはWinFormsであり、asp.netではないことに注意してください。

ありがとうございました

+2

ドロップダウンが実際にドロップダウンされる前または後に.Countプロパティを確認しましたか?アイテムのコレクションをあまりにも頻繁に再ロードするのを避けるためにいくつかの最適化が行われていると思われますので、スクリーン上にドロップするまで全体を延期する可能性があります。 –

+0

これは.NETのどのバージョンですか? Visual Studio 2008では、2.0または3.5のいずれかでコンパイルすると、一度に正しい数の項目が生成されます。 –

+1

動的に作成されたコンボボックスでVS2012でこの問題が発生しました –

答えて

6

動的に追加されたコンボボックスでこの問題が発生した場合は、フォーム内のコンテナのコントロールにコンボボックスを追加することをお勧めします。

「this.Controls.Add(cbo);」を追加すると、データソースを設定する前にコードに問題がなくなります。

+0

-1、間違いです。また、ComboBoxがすでにWindowsハンドルを持たないコンテナに含まれている場合にも発生します。 – TheBlastOne

+0

私は-1がここで公正ではないと思います。なぜなら、これが起こる別の理由が見つかったからです。この答えは、上記の例の問題を解決しました。 – Madeleine

+0

回答を編集しない限り元に戻すことができません。どのような種類の編集ルールがそのフロントエンドの背後にあるのか不思議に思っています... – TheBlastOne

12

すぐにカウントをチェックしましたか? UIリフレッシュなどの操作があり、その時間までカウントがオフになるまで、ComboBoxは内容を実際に更新しない可能性があります。

場合によっては、コンボボックスのハンドルが作成される前にデータソースを更新することがあります。私はリフレクター上で少しコードを掘って、ComboBoxが実際に作成されレンダリングされるまで、アイテムはこのケースで更新されないようです。 「DataSourceChanged」-eventは、多分それはちょうど明確にする

+1

コードの直後にItems.Countプロパティをチェックしています。なぜなら、その時点でもう少し論理を行う必要があるからです。 – Madeleine

+0

データソース内の項目数を確認する方が簡単でしょうか? – scraimer

+0

問題は、選択した項目を通常新しい項目に設定する必要があり、その項目が存在しないということです。 – Madeleine

0

あなたは私が見つけたのDataBind()メソッド

0

を助けることができる...もあります

+0

これはwinformsのコンボボックスで、databind()はありません –

5

を呼び出した後、カウント()メソッド を呼び出しています原因...

私はcbo.Datasource = null行..を取り出し、最後にcbo.Invalidate()を追加しました。これは問題を解決しました。

アドバイスありがとうございます。

+1

あなた自身の解決策を見つけました。あなた自身の答えを受け入れてください。 +1 –

+0

データソースを設定する前に、この行を追加する必要があります。 'cbo.Items.clear()' –

0

このコードは私のためにメッセージボックスに2を生成します。試してみて、どのように動作するか見てみましょうか?

コンソールアプリケーションに貼り付け、System.Windows.FormsおよびSystem.Drawingへの参照を追加できます。

using System; 
using System.Collections.Generic; 
using System.Windows.Forms; 
using System.Drawing; 

namespace SO887803 
{ 
    static class Program 
    { 
     [STAThread] 
     static void Main() 
     { 
      Application.Run(new MainForm()); 
     } 
    } 

    public partial class MainForm : Form 
    { 
     private Button _Button; 
     private ComboBox _ComboBox; 

     public MainForm() 
     { 
      _Button = new Button(); 
      _Button.Text = "Test"; 
      _Button.Location = new Point(8, 8); 
      _Button.Click += _Button_Click; 
      Controls.Add(_Button); 

      _ComboBox = new ComboBox(); 
      _ComboBox.Location = new Point(8, 40); 
      Controls.Add(_ComboBox); 
     } 

     private void _Button_Click(object sender, EventArgs e) 
     { 
      List<Item> items = new List<Item>(); 
      items.Add(new Item("A", "a")); 
      items.Add(new Item("B", "b")); 

      _ComboBox.DataSource = null; 
      _ComboBox.DataSource = items; 
      _ComboBox.DisplayMember = "Title"; 
      _ComboBox.ValueMember = "Value"; 
      MessageBox.Show("count: " + _ComboBox.Items.Count); 
     } 

     public class Item 
     { 
      public String Title { get; set; } 
      public String Value { get; set; } 
      public Item(String title, String value) 
      { 
       Title = title; 
       Value = value; 
      } 
     } 
    } 
} 
0

comboBox1.DataSource = somelist;

int c1 = comboBox1.DataSource.Count; //まだゼロです

BindingContext dummy = this.comboBox1.BindingContext; //強制的に更新してください!

int c2 = comboBox1.DataSource.Count; //今、それはあなたが単にpreformLayout()関数によってUIを更新することができます

、somelist.Count

+0

動作しません。申し訳ありません。 – TheBlastOne

-1

のBaサラムに等しいです。

例:

comboBox1。performLayout();

よろしく モフセンの

+0

動作しません。ごめんなさい。 – TheBlastOne

-1

これを試してください。私は今日会ったよう

cbo.Parent = <your panel control>; 
cbo.DataSource = null; 
cbo.DataSource = cbos; cbo.DisplayMember = "Title"; 
cbo.ValueMember = "Value"; 
MessageBox.Show(string.Format("itemcount is {0}", cbo.Items.Count); 

私はあなたの質問のsamesを考えます。

0

私は同じ問題がありました(私はVS 2005で働いています)。

DataSourceをnullに設定し、項目をクリアし、データソースを再割り当てし、メンバーを表示および値付けします。

例:

cbo.DataSource = null;

cbo.Items.Clear();

cbo.DataSource = cbos;

cbo.DisplayMember = "Title";

cbo.ValueMember = "Value";

+0

ComboBoxが既にWindowsハンドルを取得している場合にのみ機能します。 – TheBlastOne

4
cbo.DataSource = null; 
cbo.DataSource = cbos; 
cbo.DisplayMember = "Title"; 
cbo.ValueMember = "Value"; 

は今cbo.SelectedValueを設定、または最新であることをItemsに頼る前に、

cbo.CreateControl ; 

Itemsを呼び出すと、再計算されます。

問題がItemsリストによると、法的な値を受け入れ、WinFormsのプロパティである、SelectedValue/SelectedIndexということですが、その一つは唯一のGUIとの対話の後に構築されている、すなわち「真の」WindowsのGUIコンボをインスタンス化した後コンボボックスのWindowsハンドルを取得した後。

CreateControlは、Windowsのハンドルの作成を強制します。

+0

CreateControlは私の問題を解決しませんでした。コレクションにコントロールを追加しました。 – Brad

+1

私のためにCreateControlを追加しました –

0

古いスレッドですが、私はbindingcontextのサスペンド/レジューム、バインディングソースへのバインディングとリセット、フォームの再読み込みだけでこれらのソリューションのいくつかを試しました。私の.datasource設定時に新しくバインドされたデータで自分のコントロールを更新することはできませんでした(私のitems.countはOPのように空でした)。

私は、コンボボックスがコードの最初に削除されていたタブページ上にあり、後で(データバインド後に)再追加されたことに気付きました。バインディングイベントは発生しませんまでタブページが再追加されました。

振り返ってみると明らかですが、呼び出しの順番や状況が変化しているのを見ることができないため、実行時に検出することは非常に困難でした。コントロールは、そのコンテナに追加された後

0
ComboBox cbNew = new ComboBox(); 
    cbNew.Name = "cbLine" + (i+1); 
    cbNew.Size = cbLine1.Size; 
    cbNew.Location = new Point(cbLine1.Location.X, cbLine1.Location.Y + 26*i); 
    cbNew.Enabled = false; 
    cbNew.DropDownStyle = ComboBoxStyle.DropDownList; 
    cbNew.DataSource = DBLayer.GetTeams(lineName).Tables[0]; 
    cbNew.DisplayMember = "teamdesc"; 
    cbNew.ValueMember = "id"; 
    Console.WriteLine("ComboBox {0}, itemcount={1}", cbNew.Name, cbNew.Items.Count); 
     // The output displays itemcount = 0 for run-time created controls 
     // and >0 for controls created at design-time 
    gbLines.Controls.Add(cbNew); 

ComboBox cbNew = new ComboBox(); 
    cbNew.Name = "cbLine" + (i+1); 
    cbNew.Size = cbLine1.Size; 
    cbNew.Location = new Point(cbLine1.Location.X, cbLine1.Location.Y + 26*i); 
    cbNew.Enabled = false; 
    cbNew.DropDownStyle = ComboBoxStyle.DropDownList; 
    Console.WriteLine("ComboBox {0}, itemcount={1}", cbNew.Name, cbNew.Items.Count); 
     // The output displays itemcount = 0 for run-time created controls 
     // and >0 for controls created at design-time 
    gbLines.Controls.Add(cbNew); 
    cbNew.DataSource = DBLayer.GetTeams(lineName).Tables[0]; 
    cbNew.DisplayMember = "teamdesc"; 
    cbNew.ValueMember = "id"; 

データソースに、DisplayMemberとValueMemberでプロパティを設定する必要があります。

関連する問題