当selectitem数据被修改时,ListBox失去了更改selecteditem的能力

时间:2013-03-12 15:53:38

标签: wpf

一两天我一直试图找出一个奇怪的WPF错误。我有一个ListBox的控件绑定到PolicyId的ObservableCollection,它是一个类实现INotifyProperty和IEquatable,并且只有一个字段,称为Id(这是一个字符串)。 PolicyId是指向各种policicy项目的指针,这些项目修改了程序其他部分的工作流程。

ListBox绑定到集合,并且有一个添加和删除按钮,只需添加和删除Id到ListBox。还有一个下拉ComboBox,可用于将ListBox中selectedItem的PolicyId更改为另一个Id(可供选择的Id可在其他地方修改)。设置ListBox.SelectedItem.Id属性的值在后端完成时触发ComboBox.SelectionChanged事件,并在组合框的值发生改变时触发ListBox.SelectionChanged事件,是为了确保没有任何项目在ListBox完全相同。

现在,这个实现大部分都有效。列表框中列出了所有策略,您可以添加新策略(在列表底部添加第一个可用的以前未选择的策略)并选择并删除您喜欢的任何策略。

只要您没有使用comboBox将一个策略替换为另一个策略,即。一旦你这样做,索引就会停留在你改变的那个上,你无法做出选择另一个策略的事情(设置ListBox.SelectedIndex没有效果)。单击很长时间并最终抛出以下异常:“System.ArgumentException:已添加具有相同键的项目。”我怀疑这个错误是由WPF尝试将所选项添加到listBox的“selectedItems”集合引起的,即使该项已经存在或类似的东西。

我知道错误有事情做与策略ID忽略equals(是的,我想起了约束,如果说的Equals两个对象是相等的海誓山盟然后GetHashCode的也应该两个返回相同的值,所以GetHashCode的被覆盖因为在程序的其他地方使用了类似的设置而没有问题。我不知道如何搞砸了,特别是因为集合中没有任何重复。

这是ListBox:

<ListBox Name="policyIdList" MinHeight="50" ItemsSource="{Binding Path=DataItem}" IsSynchronizedWithCurrentItem="True" SelectionChanged="policyIdList_SelectionChanged">
    <ListBox.Resources>
        <Style TargetType="ScrollViewer">
            <Setter Property="HorizontalScrollBarVisibility" Value="Hidden" />
        </Style>
    </ListBox.Resources>
    <ListBox.ItemTemplate>
        <DataTemplate>
            <TextBlock DataContext="{Binding Path=Id}" Text="{Binding Converter={StaticResource PolicyIdToName}}">
                <TextBlock.ToolTip>
                    <ContentControl Content="{Binding}" ContentTemplate="{StaticResource PolicyByOidListItem}" />
                </TextBlock.ToolTip>
            </TextBlock>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

并且,对于好的措施,comboBox:

<ComboBox Name="policyIdCombo" Grid.Row="1" Grid.Column="0"
ItemTemplate="{StaticResource PolicyByOidListItem}" SelectionChanged="policyIdCombo_SelectionChanged" />

1 个答案:

答案 0 :(得分:12)

我认为问题是当你更改它的ID时你正在改变项的哈希码,而ListBox并不期望这样。 See here了解更多信息。

我刚刚将应用程序从.NET 3.5升级到4.0并遇到了这个问题。如果像我一样你无法使用固定的哈希码,那么解决方法就是:

  1. 从列表中删除要更改的对象
  2. 通知用户界面
  3. 更改对象的ID(导致更改其哈希码)
  4. 将您的对象添加回列表并通知UI更改。