views:

440

answers:

7

I've got a Windows Forms application with two ListBox controls on the same form. They both have their SelectionMode set to 'MultiExtended'.

When I change the selection of one the selection of the other changes.

Now I thought I'd done something stupid with my SelectedIndexChanged handlers so I removed them and re-wrote them from scratch, and got the problem.

So I created a brand new WinForms app and dragged two ListBoxes onto the forms surface.

In the constructor I populated them both with the following.

List<Thing> data = new List<Thing>();

for ( int i = 0; i < 50; i++ ) {
  Thing temp = new Thing();
  temp.Letters = "abc " + i.ToString();
  temp.Id = i;
  data.Add(temp);
}

listBox1.DataSource = data;
listBox1.DisplayMember = "Letters";
listBox1.ValueMember = "Id";


List<Thing> data2 = new List<Thing>();

for ( int i = 0; i < 50; i++ ) {
 Thing temp = new Thing();
 temp.Letters = "abc " + i.ToString();
 temp.Id = i;
 data2.Add(temp);
}

listBox2.DataSource = data2;
listBox2.DisplayMember = "Letters";
listBox2.ValueMember = "Id";

And then I built and ran the app.

Started selecting some values to see if the symptoms were present. And they were!

This is literally all the code I added to the form,I had not added any event handlers, I have tried it with the SelectionMode set to 'One' and 'MultiExtended'.

Can anyone give me a clue as to why this is happening.

Cheers

+1  A: 

I experienced the same when I used the same datasource on both listboxes, but creating two equal datasources solved the problem for me. I can see nothing wrong with your code. Anything particular with the Thing class ? Or does it just contain the two members Letters and Id ?

sindre j
Yes, Just the two members.A really simple class purely for my example.
Greg B
+2  A: 

I believe that your two controls are sharing a CurrencyManager. I'm not sure exactly why.
As a workaround, you could try just populating your listboxes with simple strings. Or you may want to try creating separate instances of the BindingSource component, and bind to those.

Matt Brunell
Any tips on how to get them to use different ones?
Greg B
Actually, I don't know how they are sharing one. I tried a simple example like Shaun Bowe, and the listbox selection appears independent. Can you reproduce the problem from a clean solution?
Matt Brunell
A: 

I created a new win forms app with two list boxes on it. They behave as I would expect. Can you post the complete code? Here is my code.

public partial class Form1 : Form
{
public Form1()
{
  InitializeComponent();
}

private class Thing
{
  public String Letters { get; set; }
  public Int32 Id { get; set; }
}
private void Form1_Load(object sender, EventArgs e)
{
  List<Thing> data = new List<Thing>();

  for (int i = 0; i < 50; i++)
  {
    Thing temp = new Thing();
    temp.Letters = "abc " + i.ToString();
    temp.Id = i;
    data.Add(temp);
  }

  listBox1.DataSource = data;
  listBox1.DisplayMember = "Letters";
  listBox1.ValueMember = "Id";


  List<Thing> data2 = new List<Thing>();

  for (int i = 0; i < 50; i++)
  {
    Thing temp = new Thing();
    temp.Letters = "abc " + i.ToString();
    temp.Id = i;
    data2.Add(temp);
  }

  listBox2.DataSource = data2;
  listBox2.DisplayMember = "Letters";
  listBox2.ValueMember = "Id";
}

}

Shaun Bowe
A: 

I tried to duplicate this behavior on my own machine and was unable to do so running just the code your provided.

josh
A: 

I stand corrected.

In another instance of VS in a brand new solution, this works as expected.

God only know's what i've done to make it do what it's doing

Greg B
+1  A: 

And more...

I finally got ot the bottom of it.

I was binding the two ListBoxes to the same List. by changing the code to

theListBox.DataSource = _contacts.Take(_contacts.Count).ToList();

the issue was curcumvented.

It seems that the reference to the List that it stored also caries any binding or selection information over to the other ListBox.

be careful. ;)

Greg B
+2  A: 

It isn't the list that stores the current position - it is the CurrencyManager. Any controls (with the same BindingContext) with the same reference as a DataSource will share a CurrencyManager. By using different list instances you get different CurrencyManager instances, and thus separate position.

You could achieve the same simply by using .ToList(), or creating a new List<T> with the same contents (as per your original post), or by assigning a new BindingContext to one of the controls:

control.BindingContext = new BindingContext();
Marc Gravell