tags:

views:

118

answers:

2
    public Form1()
    {
        InitializeComponent();
        comboBox1.DisplayMember = "Name";
        comboBox1.ValueMember = "ID";  
        LoadUsersToComboBox();
    }

    PersonRepository peopleRepo = new PersonRepository();

    private void LoadUsersToComboBox()
    {
        comboBox1.DataSource = peopleRepo.FindAllPeople().ToList();          
    }

    private void button2_Click(object sender, EventArgs e)
    {                        
        LoadUsersToComboBox();
    }

This method will load a comboBox with value only on the FIRST time, but not on subsequent attempts:

    private void LoadUsersToComboBox()
    {
        comboBox1.DataSource = peopleRepo.FindAllPeople(); /*Return IQueryable<Person>*/
    }

And this loads every time I call LoadUsersToComboBox():

    private void LoadUsersToComboBox()
    {
        comboBox1.DataSource = peopleRepo.FindAllPeople().ToList();
    }

Why does the first one only load the first time?

Here is the code to the PeopleRepository class:

namespace SQLite_Testing_Grounds
{
    public class PersonRepository
    {
        private ScansEntities3 db = new ScansEntities3();

        public IQueryable<Person> FindAllPeople()
        {
            return db.People;
        }
    }
}
A: 

In this call, you are setting the datasource, but not the databind call to actually bind the data. Can you post the method where you call .databind?

Steven Raines
I never call DataBind.
Serg
@Steven Raines ~ Wrong platform, so to speak. He's using something more akin to live databinding, I presume you, like I, work in ASP.NET...
drachenstern
+2  A: 

Solution is simple :

// This method returns the same reference every time
public IQueryable<Person> FindAllPeople()
{
    return db.People;
}

As a result :

// Nothing changes, DataSource old value is still the same (same reference,
// even is the content of the People list does change).
comboBox1.DataSource = peopleRepo.FindAllPeople();

// ToList() creates a new object each time, so DataSource is assigned to a 
// NEW object, and so calls a kind of invalidation of its visual.
comboBox1.DataSource = peopleRepo.FindAllPeople().ToList();

.
That's a data-binding basics, actually I'm not at all a WinForms guy (I know a lot more about WPF), but I think that internally, you have someting similar than :

private object dataSource;
public object DataSource {
    get {
        if (value != dataSource) {
            dataSource = value;
            RaisePropertyChanged("DataSource");
        }
    }
}
Aurélien Ribon
This makes sense. Can anyone confirm?
Serg
Actually, you should try with setting DataSource to null or to a new empty List before calling FindAllpeople(). Don't know if the compiler will optimize this and silently remove the intermediate, but if not, you should get the same result, without the overhead of calling the ToList() method.
Aurélien Ribon
I have tried using DataSource = null; before posting this question, but the result was the same. No changes.
Serg
So the compiler optimizes this and removes the null association.
Aurélien Ribon