У меня есть объект, который имеет некоторые атрибуты из выбранного списка - скажем, промоушн, который может иметь каналы связи от 0 до X. Чтобы отображать/редактировать эту информацию, я использую список с опцией SelectionMode == MultiExtended.
Но в некоторых случаях это ведет себя странно
У меня есть Продвижение с двумя выбранными каналами связи (первый и последний из трех каналов),
Я щелкаю по второму каналу (который ранее был единственным невыбранным каналом) и знал, что он показывает, что выбраны 1-й и 2-й каналы (я поставил чек в начале списка SelectedIndexChanged event - и он показывает, что SelectedItems.Count == 2, хотя я нажал на один элемент, не удерживая клавиши Ctrl или Shift), и в этом случае событие SelectedIndexChanged запускается дважды во всех остальных случаях, он запускается только один раз
Это происходит только после первого открытия этого диалогового окна, если я вручную выбираю 1-й и 3-й позиции каналов, а затем выбираю второй элемент - тогда он работает правильно
http://screencast.com/t/lVs0e9oau
foreach (var ct in Promotion_operations.Configuration.PromoCommunicationTypes)
{
KeyValuePair<string, PromotionCommunicationType> nct =
new KeyValuePair<string, PromotionCommunicationType>(ct.Name, ct);
communications.Add(nct);
}
PromotionCommunicationList.DataSource = communications; //Promotion_operations.Configuration.PromoCommunicationTypes;
PromotionCommunicationList.DisplayMember = "Key";
PromotionCommunicationList.ValueMember = "Value";
private void LoadSelectedCommunicationsList(ListBox lstbox, List<PromotionCommunication> communications)
{
lstbox.SelectedItems.Clear();
foreach (var ct in communications)
{
for (int j = 0; j < lstbox.Items.Count; j++)
{
if (ct.CommunicationType.Id == ((KeyValuePair<string, PromotionCommunicationType>)lstbox.Items[j]).Value.Id)
{
lstbox.SelectedItems.Add(lstbox.Items[j]);
}
}
}
}
что нажатие на один ранее невыбранный список выбирает как новый выбранный элемент, так и первый элемент списка?
Ваш список PromotionCommunicationList
и HistoryCommunicationList
разделяют ту же ссылку на ваш список объектов, что и DataSource
. Тем не менее, они имеют один и тот же BindingContext
и используют BindingContext
и тот же CurrencyManager
. CurrencyManager
запоминает выбранные элементы вашего элемента управления ListBox
и создает конфликт, потому что он сохраняет выбранные элементы обоих ваших ListBoxes
. Вы уже нашли решение своей проблемы, потому что новый CurrencyManager
создается, когда вы устанавливаете "другой" список (копию исходного) как DataSource
. Другим возможным решением было бы создание нового BindingContext
для одного из ваших элементов управления ListBox
.
Вы можете попробовать:
PromotionCommunicationList.DataSource = communications;
(..)
HistoryCommunicationList.BindingContext = new BindingContext(); // Add this
HistoryCommunicationList.DataSource = communications;
Он должен решить вашу проблему. Для получения дополнительной информации о BindingContext проверьте эту ссылку в MSDN.
Я нашел причину проблемы, хотя я действительно не понимаю, почему это вызвало такое поведение (если кто-то ответит на этот вопрос, я буду принимать его как ответ на этот вопрос)
У меня было 2 списка в моей форме, и оба они использовали ту же коллекцию, что и Datasource, НО !!! SelectedItems была выбрана с использованием кода (по-видимому, кажется, что в winforms невозможно отобразить список выбранных данных)
PromotionCommunicationList.DataSource = communications;
(..)
HistoryCommunicationList.DataSource = communications;
PromotionCommunicationList.DataSource = communications.ToList();
(..)
HistoryCommunicationList.DataSource = communications.ToList();
Я знаю, что ToList() делает копию, но я не понимаю, что неправильно с тем же набором, что и DataSource для элементов списка из 2 listbox-es? Почему это влияет на коллекцию SelectedItems?