Note that there are some explanatory texts on larger screens.

plurals
  1. POWPF ListBox & Items with Changing Hashcode
    text
    copied!<p>I have a <code>ListBox</code> bound to a collection of items that have an ID that is used to generate the result of <code>GetHashCode()</code>. When a new item is added, it has ID 0 until it is first saved to our database. This is causing my <code>ListBox</code> to complain; I believe the reason is because when an item is first used by a <code>ListBox</code> it is stored in an internal <code>Dictionary</code> that does not expect the hashcode to change.</p> <p>I can fix this by removing the unsaved item from the collection (I <strong>must</strong> notify the UI at this stage to remove it from the dictionary), save to the DB, and add it back to the collection. This is messy and I do not always have access to the collection from my <code>Save(BusinessObject obj)</code> method. Does anyone have an alternative solution to this problem?</p> <p>EDIT In respose to Blam's answer:</p> <p>I am using MVVM so I have modified the code to use bindings. To reproduce the problem click add, select the item, click save, repeat, then try to make a selection. I think this demonstrates that the <code>ListBox</code> is still holding onto the old hashcodes in it's internal <code>Dictionary</code>, hence the conflicting keys error.</p> <pre><code>&lt;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"&gt; &lt;Grid&gt; &lt;Grid.RowDefinitions&gt; &lt;RowDefinition Height="Auto"/&gt; &lt;RowDefinition Height="*"/&gt; &lt;/Grid.RowDefinitions&gt; &lt;StackPanel HorizontalAlignment="Center" Orientation="Horizontal"&gt; &lt;Button Click="Button_Click_Add" Content="Add"/&gt; &lt;Button Click="Button_Click_Save" Content="Save Selected"/&gt; &lt;/StackPanel&gt; &lt;ListBox Grid.Row="1" ItemsSource="{Binding List}" DisplayMemberPath="ID" SelectedItem="{Binding Selected}"/&gt; &lt;/Grid&gt; &lt;/Window&gt; public partial class MainWindow : Window { public ObservableCollection&lt;ListItem&gt; List { get; private set; } public ListItem Selected { get; set; } private Int32 saveId; public MainWindow() { this.DataContext = this; this.List = new ObservableCollection&lt;ListItem&gt;(); 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 &amp;&amp; Selected.ID == 0) { Selected.ID = saveId; saveId++; } } } </code></pre> <p>EDIT 2 After some testing, I have discovered a few things:</p> <ul> <li><p>Changing the hash code of an item in a <code>ListBox</code> seems to work ok.</p></li> <li><p>Changing the hash code of <em>the selected item</em> in a <code>ListBox</code> breaks<br> it's functionality.</p></li> </ul> <p>When a selection made (single or multiple selection mode) the <code>IList ListBox.SelectedItems</code> is updated. Items that are added to the selection are added to <code>SelectedItems</code> and items that are no longer included in the selection are removed.</p> <p>If the hash code of an item is changed while it is selected, there is no way to remove it from <code>SelectedItems</code>. Even manuallty calling <code>SelectedItems.Remove(item)</code>, <code>SelectedItems.Clear()</code> and setting <code>SelectedIndex</code> to -1 all have no effect, and the item remains in the <code>IList</code>. This causes exceptions to be thrown after the next time it is selected as I believe it is once again added to <code>SelectedItems</code>.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload