Изменение выбора ListBox изменяет выбор другого ListBox. В чем дело? - PullRequest
1 голос
/ 13 ноября 2008

У меня есть приложение Windows Forms с двумя элементами управления ListBox в одной форме. Для обоих из них для SelectionMode установлено значение «MultiExtended».

Когда я меняю выбор одного, выбор другого меняется.

Теперь я подумал, что сделал что-то глупое с моими обработчиками SelectedIndexChanged, поэтому я удалил их, переписал их с нуля и получил проблему.

Итак, я создал новое приложение WinForms и перетащил два ListBox на поверхность форм.

В конструкторе я заполнил их обоих следующим:

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

А потом я собрал и запустил приложение.

Начал выбирать некоторые значения, чтобы проверить наличие симптомов. И они были!

Это буквально весь код, который я добавил в форму, я не добавил никаких обработчиков событий, я пробовал его с SelectionMode, установленным в 'One' и 'MultiExtended'.

Может кто-нибудь подсказать мне, почему это происходит.

Приветствия

Ответы [ 7 ]

4 голосов
/ 14 ноября 2008

Не список хранит текущую позицию - это CurrencyManager. Любые элементы управления (с тем же BindingContext) с той же ссылкой , что и DataSource, будут иметь CurrencyManager. Используя разные экземпляры списка, вы получаете разные экземпляры CurrencyManager и, следовательно, отдельную позицию.

Вы можете добиться того же, просто используя .ToList(), или создав новый List<T> с тем же содержимым (как в исходном сообщении), или назначив новый BindingContext одному из элементов управления:

control.BindingContext = new BindingContext();
2 голосов
/ 13 ноября 2008

Я полагаю, что ваши два элемента управления совместно используют CurrencyManager. Я точно не знаю, почему.
В качестве обходного пути вы можете попробовать просто заполнить списки простыми строками. Или вы можете попытаться создать отдельные экземпляры компонента BindingSource и выполнить привязку к ним.

1 голос
/ 14 ноября 2008

И еще ...

Наконец-то я понял.

Я связывал два ListBox с одним и тем же списком. изменив код на

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

проблема была обойдена.

Похоже, что ссылка на сохраненный список также содержит любую информацию о привязке или выборе для другого ListBox.

будь осторожен. ;)

1 голос
/ 13 ноября 2008

Я испытал то же самое, когда использовал один и тот же источник данных в обоих списках, но создание двух одинаковых источников данных решило проблему для меня. Я не вижу ничего плохого в вашем коде. Что-то особенное с классом Thing? Или он просто содержит два члена Letters и Id?

0 голосов
/ 13 ноября 2008

Я стою исправлено.

В другом экземпляре VS в новом решении это работает как ожидалось.

Бог знает только то, что я сделал, чтобы заставить его делать то, что он делает

0 голосов
/ 13 ноября 2008

Я пытался продублировать это поведение на своем компьютере и не смог сделать это, запустив только код, который вы указали.

0 голосов
/ 13 ноября 2008

Я создал новое приложение для создания форм с двумя списками. Они ведут себя так, как я ожидал. Можете ли вы опубликовать полный код? Вот мой код

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";
}

}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...