【问题标题】:Multi value ListBox automatically selects undesired item多值列表框自动选择不需要的项目
【发布时间】:2014-06-22 15:58:53
【问题描述】:

我有一个对象,它具有所选列表中的一些属性 - 假设一个可以有 0 到 X 个通信渠道的促销活动。要显示/编辑此信息,我正在使用带有选项 SelectionMode==MultiExtended 的列表框。

但在某些情况下它的行为很奇怪

  1. 我选择了 2 个沟通渠道(三个渠道中的第一个和最后一个)进行促销,

  2. 我单击第二个频道(以前是唯一未选择的频道)并知道它显示了第一个和第二个频道已被选中(我在列表框 SelectedIndexChanged 事件的开头放置了一个检查 - 它显示SelectedItems.Count==2,虽然我点击了一个没有按住 Ctrl 或 Shift 键的项目)在这种情况下 SelectedIndexChanged 事件被触发两次在所有其他情况下它只被触发一次

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

这是我根据 Promotion 的数据加载选定项目的方式

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]);
            }
        }
    }
}

此行为的原因可能是什么?

单击一个以前未选择的列表会同时选择新选择的项目和列表的第一项?

【问题讨论】:

  • 所以您的意思是,例如,您在列表框中有 10 个项目,您选择例如第三个项目,还会选择什么?
  • @terrybozzio 第三个也是第一个将被选中,但是当我第二次重复它时,它会正常工作。实际上它只发生在一个特定的场景中(我描述的那个 - 如果最初选择了第一个和第三个项目并且我手动点击第二个项目 - 结果我选择了第一个和第二个项目)
  • @terrybozzio,在这种情况下,当该第一个项目被自动选择时 - 然后列出了Listbox的SelectedIndexChanged事件两次触发,但是在其他情况下(选择正常工作时)此事件仅一次触发。 >
  • 你试过listbox.clearSelected()方法吗?
  • @terrybozzio 我需要一个选项来选择多个值...但我不知道在哪个地方可以使用它?在列表框中单击事件?但是我应该以某种方式只过滤我不尝试多选(不使用 Ctrl、Shift 键)的情况?

标签: c# winforms listbox


【解决方案1】:

您的PromotionCommunicationListHistoryCommunicationListDataSource 共享对您的对象列表的相同引用。也就是说,它们具有相同的BindingContext 并共享相同的CurrencyManagerCurrencyManager 正在记住您的 ListBox 控件的选定项目,这就是您的冲突产生的地方,因为他正在保存您的两个 ListBoxes 的选定项目。您已经找到了问题的解决方案,因为当您将 “不同” 列表(原始列表的副本)设置为 DataSource 时,会创建新的 CurrencyManager。另一种可能的解决方案是为您的ListBox 控件之一创建新的BindingContext
你可以试试这个:

PromotionCommunicationList.DataSource = communications;
(..)
HistoryCommunicationList.BindingContext = new BindingContext(); // Add this
HistoryCommunicationList.DataSource = communications;

它应该可以解决您的问题。有关 BindingContext 的更多信息,请查看 MSDN 上的 this 链接。

【讨论】:

    【解决方案2】:

    我找到了问题的原因,虽然 我真的不明白为什么会导致这种行为如果有人会回答这个问题,我会接受它作为对这个问题)

    我的表单中有 2 个列表框,并且它们都使用与数据源相同的集合,但是!!! 使用代码选择了 SelectedItems(实际上在 winforms 中似乎是无法对列表框的选定项进行数据绑定)

    最初我的代码是:

    PromotionCommunicationList.DataSource = communications;
    (..)
    HistoryCommunicationList.DataSource = communications;
    

    更正的版本是:

    PromotionCommunicationList.DataSource = communications.ToList();
    (..)
    HistoryCommunicationList.DataSource = communications.ToList();
    

    我知道 ToList() 制作了一个副本,但我不明白对于 2 个列表框的列表项使用与 DataSource 相同的集合有什么问题?为什么这会对 SelectedItems 集合产生影响?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-01
      • 2021-11-26
      相关资源
      最近更新 更多