我ListBox
绑定到一组项目,这些项目的 ID 用于生成GetHashCode()
. 添加新项目时,它的 ID 为 0,直到它首次保存到我们的数据库中。这导致我ListBox
抱怨;我相信原因是因为当一个项目第一次被 a 使用时,ListBox
它被存储在一个Dictionary
不期望哈希码改变的内部。
我可以通过从集合中删除未保存的项目来解决此问题(我必须在此阶段通知 UI 以将其从字典中删除),保存到数据库,然后将其添加回集合中。这很混乱,我并不总是可以通过我的Save(BusinessObject obj)
方法访问该集合。有没有人有这个问题的替代解决方案?
编辑响应 Blam 的回答:
我正在使用 MVVM,所以我修改了代码以使用绑定。要重现问题,请单击添加,选择项目,单击保存,重复,然后尝试进行选择。我认为这表明它ListBox
仍然在其内部保留旧的哈希码Dictionary
,因此出现冲突键错误。
<Window x:Class="ListBoxHashCode.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel HorizontalAlignment="Center" Orientation="Horizontal">
<Button Click="Button_Click_Add" Content="Add"/>
<Button Click="Button_Click_Save" Content="Save Selected"/>
</StackPanel>
<ListBox Grid.Row="1" ItemsSource="{Binding List}" DisplayMemberPath="ID" SelectedItem="{Binding Selected}"/>
</Grid>
</Window>
public partial class MainWindow : Window {
public ObservableCollection<ListItem> List { get; private set; }
public ListItem Selected { get; set; }
private Int32 saveId;
public MainWindow() {
this.DataContext = this;
this.List = new ObservableCollection<ListItem>();
this.saveId = 100;
InitializeComponent();
}
private void Button_Click_Add(object sender, RoutedEventArgs e) {
this.List.Add(new ListItem(0));
}
private void Button_Click_Save(object sender, RoutedEventArgs e) {
if (Selected != null && Selected.ID == 0) {
Selected.ID = saveId;
saveId++;
}
}
}
编辑 2 经过一些测试,我发现了一些事情:
更改 a 中项目的哈希码
ListBox
似乎可以正常工作。更改所选项目的哈希码
ListBox
会破坏
其功能。
当进行选择(单选或多选模式)时,IList ListBox.SelectedItems
更新。添加到选择中的项目被添加到选择中SelectedItems
,不再包含在选择中的项目被删除。
如果在选择项目时更改了项目的哈希码,则无法将其从SelectedItems
. 即使是手动调用SelectedItems.Remove(item)
,SelectedItems.Clear()
设置SelectedIndex
为 -1 都没有效果,并且该项目保留在IList
. 这会导致在下次选择它之后抛出异常,因为我相信它会再次添加到SelectedItems
.