views:

4829

answers:

11

Hi

I have a combobox that is bound to a datasource. I want to dynamically add items to the combo box based on certain conditions. So, what I've done is add the options to a new list, and then change the datasource of the combobox like so:

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

Then, I check the cbo.Items.Count, and it has not incremented - it does not equal to the count of the datasource. Any ideas what I can do here? Note this is WinForms and not asp.net.

Thanks

+5  A: 

Did you check the Count immediately or at a later time? There is the possibility that the ComboBox does not actually update it's contents until there is an operation such as a UI refresh and hence the count will be off until that time.

On case where this may happen is if you update the DataSource before the Handle is created for the ComboBox. I dug through the code a bit on reflector and it appears the items will not be updated in this case until the ComboBox is actually created and rendered.

JaredPar
I'm checking the Items.Count property immediately after in code, because I need to then do some more logic at that point.
Vixen
Wouldn't it be simpler to check the number of items in your data source?
scraimer
The problem is that I have to set the selected item, usually to the new one, and that index doesnt exist.
Vixen
Came across this issue again somewhere else in code. The issue is that the combo box is being added at run time and therefore as Jared mentioned, no handle has been created for the combo box. By adding "this.Controls.Add(cbo);" the problem disappears.
Vixen
A: 

There's also an "DataSourceChanged"-event...maybe that could help

Scoregraphic
A: 

Just to clarify are you calling the count() method After calling the databind() method

This is a winforms combobox, there's no databind()
Jose Basilio
+3  A: 

I've found the cause...

I took out the cbo.Datasource = null line.. and added a cbo.Invalidate() at the end. This has solved the problem.

Thanks all for the advice.

Vixen
Found your own solution. Go ahead and accept your own answer. +1
Jose Basilio
A: 

This code produces 2 in the message box for me, can you try it and see how it behaves for you?

You can paste it into a console application, and add a reference to System.Windows.Forms and 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;
            }
        }
    }
}
Lasse V. Karlsen
A: 

comboBox1.DataSource=somelist;

int c1=comboBox1.DataSource.Count; // still zero

BindingContext dummy = this.comboBox1.BindingContext;// Force update NOW!

int c2=comboBox1.DataSource.Count; // now it equals somelist.Count

A: 

Ba salam,

you can simply refresh the UI by preformLayout() function;

Example:

comboBox1.performLayout();

regards mohsen s

A: 

Ba salam

if it didn't work. first assign null to datasource. and then assign your favorite datasource. I am sure it will work.

regards

A: 

please try this:

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

I think your question sames like I met today.

A: 

I had the same problem (Im working with VS 2005).

What you need to do is set the DataSource to null, clear the items, reassign the datasource , display and value members.

Eg

cbo.DataSource = null;

cbo.Items.Clear();

cbo.DataSource = cbos;

cbo.DisplayMember = "Title";

cbo.ValueMember = "Value";

A: 

If anyone experiences this problem on a dynamically added combobox, the answer is to ensure that you add the combobox to the controls of a container in the form.

By adding "this.Controls.Add(cbo);" to the code before setting the datasource, the problem goes away.

Vixen