【问题标题】:ComboBox items.count doesn't match DataSourceComboBox items.count 与 DataSource 不匹配
【发布时间】:2010-10-27 15:10:03
【问题描述】:

我有一个绑定到数据源的组合框。我想根据某些条件向 ComboBox 动态添加项目。所以我所做的就是将选项添加到一个新列表中,然后像这样更改 ComboBox 的 DataSource:

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

然后,我检查cbo.Items.Count,它没有增加 - 它不等于 DataSource 的计数。任何想法我可以在这里做什么?

注意这是 WinForms 而不是 ASP.NET。

【问题讨论】:

  • 您是否在下拉列表实际下拉之前或之后检查了 .Count 属性?我怀疑正在进行一些优化以避免过于频繁地重新加载项目集合,所以它可能会推迟整个事情,直到你真正将它放到屏幕上。
  • 这是哪个版本的 .NET?在 Visual Studio 2008 中,为 2.0 或 3.5 编译一次会生成正确数量的项目。
  • 我在 VS2012 中使用动态创建的组合框遇到了这个问题

标签: c# winforms data-binding combobox


【解决方案1】:

您是立即还是稍后检查计数? ComboBox 有可能在进行诸如 UI 刷新之类的操作之前实际上不会更新其内容,因此在此之前计数将关闭。

如果您在为组合框创建句柄之前更新数据源,则可能发生这种情况。我在反射器上挖掘了一些代码,在这种情况下,在实际创建和渲染 ComboBox 之前,项目似乎不会更新。

【讨论】:

  • 我在代码之后立即检查 Items.Count 属性,因为那时我需要做更多的逻辑。
  • 检查数据源中的项目数不是更简单吗?
  • 问题是我必须设置选中的项目,通常是新的,而且那个索引不存在。
  • 在代码的其他地方再次遇到这个问题。问题是组合框是在运行时添加的,因此正如 Jared 所提到的,没有为组合框创建句柄。通过添加“this.Controls.Add(cbo);”问题消失了。
【解决方案2】:

如果有人在动态添加的组合框上遇到此问题,答案是确保将组合框添加到表单中容器的控件中。

通过添加“this.Controls.Add(cbo);”设置数据源之前的代码,问题就消失了。

【讨论】:

  • -1,不真实。如果 ComboBox 已经包含在还没有 Windows 句柄的容器中,也会发生这种情况。
  • 我不认为 -1 在这里是公平的,只是因为您找到了发生这种情况的另一个原因。这个答案解决了所述示例中的问题。
  • 除非编辑答案,否则无法撤消。我一直想知道so的前端背后有什么样的编辑规则......
【解决方案3】:

我找到了原因……

我取出 cbo.Datasource = null 行......并在最后添加了一个 cbo.Invalidate() 。这解决了这个问题。

感谢大家的建议。

【讨论】:

  • 找到您自己的解决方案。来吧,接受你自己的答案。 +1
  • 您应该在设置数据源之前添加这一行。 cbo.Items.clear()
【解决方案4】:
cbo.DataSource = null; 
cbo.DataSource = cbos; 
cbo.DisplayMember = "Title"; 
cbo.ValueMember = "Value"; 

现在在设置cbo.SelectedValue,或依赖Items 更新之前,请致电

cbo.CreateControl ;

Items 将被重新计算。

问题是SelectedValue/SelectedIndex,这是WinForms属性,只接受根据Items列表合法的值,但是那个是在GUI交互之后构建的,即在实例化一个“ real" Windows GUI 组合框,即在获得组合框的 Windows 句柄之后。

CreateControl 无论如何都会强制创建 Windows 句柄。

【讨论】:

  • CreateControl 没有为我解决问题。确实将控件添加到集合中。
【解决方案5】:
 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";

必须在控件添加到其容器后设置 DataSource、DisplayMember 和 ValueMember 属性。

【讨论】:

    【解决方案6】:
    By adding "this.Controls.Add(cbo);" to the code before setting the datasource, the problem goes away.   
     //Create dynamic combobox and add to Panel
        ComboBox ddCombo = new ComboBox();
        controls = new Control[1] { ddCombo };
        panel.Controls.AddRange(controls); 
    
        //After creating add to table layout
        tableLayoutPanel.Controls.Add(panel, 0, 0);
    
        ddCombo .Name = "ddName";
        ddCombo .Width = 200;
        ddCombo .Location = new Point(x, y);                                                                                                          ddCombo .DataSource = ds;//or any List
        ddCombo .SelectedIndex = ddCombo .Items.Count - 1;
    

    【讨论】:

      【解决方案7】:

      只是为了澄清你是否调用了 count() 方法 调用databind()方法后

      【讨论】:

      • 这是一个winforms组合框,没有databind()
      【解决方案8】:

      此代码为我在消息框中生成 2,您可以尝试一下,看看它对您的表现如何?

      您可以将其粘贴到控制台应用程序中,并添加对System.Windows.FormsSystem.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;
                  }
              }
          }
      }
      

      【讨论】:

        【解决方案9】:

        comboBox1.DataSource=somelist;

        int c1=comboBox1.DataSource.Count; // 还是零

        BindingContext dummy = this.comboBox1.BindingContext;// 现在强制更新!

        int c2=comboBox1.DataSource.Count; // 现在它等于 somelist.Count

        【讨论】:

          【解决方案10】:

          我遇到了同样的问题(我正在使用 VS 2005)。

          您需要做的是将 DataSource 设置为 null,清除项目,重新分配 datasource 、 display 和 value 成员。

          例如

          cbo.DataSource = null;

          cbo.Items.Clear();

          cbo.DataSource = cbos;

          cbo.DisplayMember = "标题";

          cbo.ValueMember = "价值";

          【讨论】:

          • 仅当 ComboBox 已经获得 Windows 句柄时才有效。
          【解决方案11】:

          旧线程,但我尝试了其中一些解决方案,以及暂停/恢复绑定上下文、绑定和重置绑定源,以及只是简单地重新加载表单。在我的 .datasource 设置时,没有人用新绑定的数据更新我的控件(我的 items.count 是空的,就像 OP 一样)。

          然后我意识到我的组合框位于一个标签页上,该标签页在代码开始时被删除,后来又被重新添加(在我的数据绑定之后)。 直到标签页被重新添加后,绑定事件才发生。

          回想起来似乎很明显,但在运行时很难检测到,因为调用的顺序和无法看到事情何时发生变化。

          【讨论】:

            【解决方案12】:

            试试这个代码。

            cbo.BindingContext = new BindingContext();
            cbo.DataSource = null;
            cbo.DataSource = cbos;
            cbo.DisplayMember = "Title";
            cbo.ValueMember = "Value";
            

            也许你的 ComboBox 的 BindingContext 为空。

            【讨论】:

              【解决方案13】:

              巴萨拉姆,

              您可以通过 preformLayout() 函数简单地刷新 UI;

              例子:

              comboBox1.performLayout();

              问候 莫森斯

              【讨论】:

                【解决方案14】:

                请试试这个:

                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);
                

                我想你的问题和我今天遇到的一样。

                【讨论】:

                  猜你喜欢
                  • 2021-11-19
                  • 1970-01-01
                  • 2018-09-15
                  • 1970-01-01
                  • 1970-01-01
                  • 2011-11-14
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多