title: My ListView is showing the same item twice. How do I fix it?
body: <p>I have a <code>ComboBox</code> that allows the user to select a category and a <code>ListView</code> that is bound to an <code>ObservableCollection</code> of items in the selected category. When the user selects a different category, the items in the collection are updated. Sometimes this works as expected, but sometimes the list of items is mangled. <strong>It shows a duplicate item when there should be two separate items.</strong></p>
  
  <p>The results seem to depend on which category I'm switching from. For example, if I switch from a category with no items to a category with two items, the same item is shown twice. But if I switch from a category with four items to that same category with two items, they are shown correctly.</p>
  
  <p>Here is a repro:</p>
  
  <p><strong>MainPage.xaml</strong></p>
  
  <pre><code>&lt;Page
      x:Class="ListViewDuplicateItem_Binding.MainPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:local="using:ListViewDuplicateItem_Binding"&gt;
      &lt;Grid&gt;
          &lt;Grid.ColumnDefinitions&gt;
              &lt;ColumnDefinition /&gt;
              &lt;ColumnDefinition /&gt;
          &lt;/Grid.ColumnDefinitions&gt;
          &lt;Grid.RowDefinitions&gt;
              &lt;RowDefinition Height="Auto" /&gt;
              &lt;RowDefinition /&gt;
          &lt;/Grid.RowDefinitions&gt;
          &lt;ComboBox
              Grid.Row="0"
              Grid.Column="0"
              ItemsSource="{Binding ViewModel.Groups}"
              SelectedItem="{Binding ViewModel.SelectedGroup, Mode=TwoWay}" /&gt;
          &lt;ListView
              Grid.Row="1"
              Grid.Column="0"
              ItemsSource="{Binding ViewModel.Widgets}"
              SelectedItem="{Binding ViewModel.SelectedWidget, Mode=TwoWay}"&gt;
              &lt;ListView.ItemTemplate&gt;
                  &lt;DataTemplate x:DataType="local:Widget"&gt;
                      &lt;TextBlock Text="{Binding Id}" /&gt;
                  &lt;/DataTemplate&gt;
              &lt;/ListView.ItemTemplate&gt;
          &lt;/ListView&gt;
          &lt;local:MyControl
              Grid.Row="1"
              Grid.Column="1"
              Text="{Binding ViewModel.SelectedWidget.Id, Mode=OneWay}" /&gt;
      &lt;/Grid&gt;
  &lt;/Page&gt;
  </code></pre>
  
  <p><strong>MainPage.xaml.cs</strong></p>
  
  <pre><code>using Windows.UI.Xaml.Controls;
  
  namespace ListViewDuplicateItem_Binding
  {
      public sealed partial class MainPage : Page
      {
          public MainPage()
          {
              InitializeComponent();
              DataContext = this;
          }
  
          public MainViewModel ViewModel { get; } = new MainViewModel();
      }
  }
  </code></pre>
  
  <p><strong>MainViewModel.cs</strong></p>
  
  <pre><code>using System.Collections.ObjectModel;
  using System.ComponentModel;
  using System.Linq;
  
  namespace ListViewDuplicateItem_Binding
  {
      public class MainViewModel : INotifyPropertyChanged
      {
          private string _selectedGroup;
          private Widget _selectedWidget;
  
          public MainViewModel()
          {
              PropertyChanged += HomeViewModel_PropertyChanged;
              SelectedGroup = Groups.First();
          }
  
          public event PropertyChangedEventHandler PropertyChanged;
  
          public ObservableCollection&lt;string&gt; Groups { get; } = new ObservableCollection&lt;string&gt;(DataSource.AllGroups);
  
          public string SelectedGroup
          {
              get =&gt; _selectedGroup;
              set
              {
                  if (_selectedGroup != value)
                  {
                      _selectedGroup = value;
                      PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SelectedGroup)));
                  }
              }
          }
  
          public Widget SelectedWidget
          {
              get =&gt; _selectedWidget;
              set
              {
                  if (_selectedWidget != value)
                  {
                      _selectedWidget = value;
                      PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SelectedWidget)));
                  }
              }
          }
  
          public ObservableCollection&lt;Widget&gt; Widgets { get; } = new ObservableCollection&lt;Widget&gt;();
  
          private void HomeViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
          {
              if (e.PropertyName == nameof(SelectedGroup))
              {
                  var widgetsToLoad = DataSource.GetWidgetsForGroup(SelectedGroup);
                  // Add widgets in this group
                  widgetsToLoad.Except(Widgets).ToList().ForEach(w =&gt; Widgets.Add(w));
                  // Remove widgets not in this group
                  Widgets.Except(widgetsToLoad).ToList().ForEach(w =&gt; Widgets.Remove(w));
                  // Select the first widget
                  if (SelectedWidget == null &amp;&amp; Widgets.Any())
                  {
                      SelectedWidget = Widgets.First();
                  }
              }
          }
      }
  }
  </code></pre>
  
  <p><strong>DataSource.cs</strong></p>
  
  <pre><code>using System.Collections.Generic;
  using System.Collections.ObjectModel;
  
  namespace ListViewDuplicateItem_Binding
  {
      public static class DataSource
      {
          public static ObservableCollection&lt;string&gt; AllGroups { get; } = new ObservableCollection&lt;string&gt;
          {
              "First Widget",
              "First Two Widgets",
              "Last Two Widgets",
              "All Widgets",
              "None"
          };
  
          public static List&lt;Widget&gt; AllWidgets { get; } = new List&lt;Widget&gt;
          {
              new Widget()
              {
                  Id = 1,
              },
              new Widget()
              {
                  Id = 2,
              },
              new Widget()
              {
                  Id = 3,
              },
              new Widget()
              {
                  Id = 4,
              }
          };
  
          public static List&lt;Widget&gt; GetWidgetsForGroup(string group)
          {
              switch (group)
              {
                  case "First Widget":
                      return new List&lt;Widget&gt; { AllWidgets[0] };
  
                  case "First Two Widgets":
                      return new List&lt;Widget&gt; { AllWidgets[0], AllWidgets[1] };
  
                  case "Last Two Widgets":
                      return new List&lt;Widget&gt; { AllWidgets[2], AllWidgets[3] };
  
                  case "All Widgets":
                      return new List&lt;Widget&gt;(AllWidgets);
  
                  default:
                      return new List&lt;Widget&gt;();
              }
          }
      }
  }
  </code></pre>
  
  <p><strong>Widget.cs</strong></p>
  
  <pre><code>namespace ListViewDuplicateItem_Binding
  {
      public class Widget
      {
          public int Id { get; set; }
      }
  }
  </code></pre>
  
  <p><strong>MyControl.xaml</strong></p>
  
  <pre><code>&lt;UserControl
      x:Class="ListViewDuplicateItem_Binding.MyControl"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&gt;
      &lt;TextBox Text="{x:Bind Text, Mode=TwoWay}" /&gt;
  &lt;/UserControl&gt;
  </code></pre>
  
  <p><strong>MyControl.xaml.cs</strong></p>
  
  <pre><code>using Windows.UI.Xaml;
  using Windows.UI.Xaml.Controls;
  
  namespace ListViewDuplicateItem_Binding
  {
      public sealed partial class MyControl : UserControl
      {
          public static readonly DependencyProperty TextProperty = DependencyProperty.Register(nameof(Text), typeof(string), typeof(MyControl), new PropertyMetadata(null));
  
          public MyControl()
          {
              InitializeComponent();
          }
  
          public string Text
          {
              get { return (string)GetValue(TextProperty); }
              set { SetValue(TextProperty, value); }
          }
      }
  }
  </code></pre>