の結果を生成するために使用される ID を持つListBox
アイテムのコレクションにバインドしていますGetHashCode()
。新しいアイテムが追加されると、最初にデータベースに保存されるまで ID 0 になります。ListBox
これは私が不平を言う原因です。その理由は、アイテムが最初に使用されたときに、ハッシュコードが変更されることを予期しないListBox
内部に格納されているためだと思います。Dictionary
保存されていないアイテムをコレクションから削除することでこれを修正できます (この段階で UI に通知して辞書から削除する必要があります)。DB に保存し、コレクションに追加し直します。Save(BusinessObject obj)
これは面倒で、メソッドからコレクションに常にアクセスできるとは限りません。誰かがこの問題の別の解決策を持っていますか?
編集ブラムの答えに応えて:
MVVM を使用しているため、バインディングを使用するようにコードを変更しました。問題を再現するには、[追加] をクリックし、アイテムを選択して [保存] をクリックし、繰り返してから、選択を試みます。ListBox
これは、がまだ internal の古いハッシュコードを保持していることを示していると思い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++;
}
}
}
EDIT 2いくつかのテストの後、いくつかのことを発見しました:
アイテムのハッシュ コードを変更しても問題
ListBox
ないようです。選択したアイテムのハッシュ コードを変更すると、その機能が
ListBox
壊れ
ます。
選択が行われると (単一または複数選択モード)、IList ListBox.SelectedItems
が更新されます。選択に追加されたアイテムは追加され、選択にSelectedItems
含まれなくなったアイテムは削除されます。
アイテムが選択されている間にアイテムのハッシュ コードが変更された場合、それを から削除する方法はありませんSelectedItems
。を手動で呼び出してもSelectedItems.Remove(item)
-1SelectedItems.Clear()
に設定SelectedIndex
しても効果はなく、アイテムは に残りIList
ます。これにより、次回に選択されたときに例外がスローされSelectedItems
ます。