从 WPF 列表框中删除重复项时出现奇怪的结果

Strange result when removing duplicated item from a WPF ListBox

这是我的代码:

public SelectorDemo()
{
    InitializeComponent();

    List<string> strs = new List<string>()
    {
        "AAAAAAAAAAAAAAAAAAAAA",
        "BBBBBBBBBBBBBBBBBBBBBBBB",
        "CCCCCCCCCCCCCCCCCCCCCCCC",
        "DDDDDDDDDDDDDDDDDDDDDDDD",
    };

    for (int i = 0; i < strs.Count; i++)
    {
        this.listBox1.Items.Add(strs[i]);
    }

    _ccc = strs[2];
    listBox1.Items.Insert(0, _ccc);
}

private void btn_Click(object sender, RoutedEventArgs e)
{
    listBox1.Items.Remove(0);
}

private void listBox1_SelectionChanged(object sender, SelectionChangedEventArgs e)
{

}    

您可以看到我的 ListBox 现在有 5 个项目 ("CC..","AA..","BB..","CC..","DD.."),我有一个按钮可以删除任何项目。

如果您 select 第 4 个项目(第二个 "CC..")然后单击删除索引为 0 的项目的按钮(第一个 "CC.."),您会发现ListBox.SelectionChanged 事件未触发。

但是,如果您将第二个 "CC.." 插入到第一个之前(这意味着第二个 "CC.." 的索引为 2,第一个 "CC.." 的索引是 3) 然后 select 第一个 "CC." 并单击按钮删除第二个“CC..”,ListBox.SelectionChanged 事件被触发。

太奇怪了,有人能帮帮我吗?我希望在第二种情况下不会触发该事件。

ListBox 不会更改 SelectedItems,如果当前选定的项目和新的项目通过 object.Equals() 方法

相等,则不会触发 SelectionChanged

事件触发是因为当从 ListBox 中删除一个项目时,它首先递减索引大于被删除项目索引的项目的索引,然后检查“选择是否更改?”。 此检查也考虑了索引。

在你的例子中,选中的“CCC”的索引是 3 而同一个未选中的“CCC”的索引是 2,当你删除未选中的“CCC”时,列表框会记住删除的“CCC”的索引" 当去掉 (2) 时,然后递减所有大于 2 的项目索引,选中的 "CCC" 的索引现在也为 2,当检查“选择是否改变?”时,选中项目的值 ( "CCC") 及其新索引 (2) 与已删除项 ("CCC") 的值和已删除项的索引 (2) 进行比较,比较结果为真,ListBox 触发 SelectionChanged。

为了避免在 ListBoxItem 中使用相同内容的包装项目,将 ListBoxItem 添加到 ListBox.Items:

    itemWithSameContent = strs[2];
    listBox1.Items.Insert(0, new ListBoxItem(){Content = itemWithSameContent});