title: WPF - not refreshing data in DataGrid when i remove items from dictionary
body: <p>I have problem with binding dictionary and delete and adding ellements to dictionary.</p>
  
  <p>1th:</p>
  
  <p>I have base class named 'Produkt' </p>
  
  <pre><code>public class Produkt : ICloneable, INotifyPropertyChanged
  {
  
      private string producent;
      public string Producent
      {
          get { return producent; }
          set { producent = value;
          OnPropertyChanged("Producent");
          }
      }
  
  
      private string nameProduct;
      public string NameProduct
      {
          get { return nameProduct; }
          set { nameProduct = value;
          OnPropertyChanged("NameProduct");
          }
      }
  
      private double cena;
      public double Cena
      {
          get { return cena; }
          set { cena = value;
          OnPropertyChanged("Cena");
          }
      }
  
  
  
      private int ilosc;
      public int Ilosc
      {
          get { return ilosc; }
          set { ilosc = value;
          OnPropertyChanged("Ilosc");
          }
      }
  
      private String kodKreskowy; // prawie jak xD
      public String KodKreskowy
      {
          get { return kodKreskowy; }
          set { kodKreskowy = value;
          OnPropertyChanged("KodKreskowy");
          }
      }
  
  
  
  
  
  
      protected Produkt(string Producent, string NazwaProduktu, double Cena, int Ilosc)
      {
          this.Producent = Producent;
          this.nameProduct = NazwaProduktu;
          this.ilosc = Ilosc;
          this.cena = Cena;
  
          this.KodKreskowy = this.ToString();
  
      }
  
  
  
  
      #region INTERFACE IMPLEMENTATION ICloneable
      public virtual object Clone()
      {
          return this.MemberwiseClone();
      }
      #endregion
      public override string ToString()
      {
          return GetKodKreskowy();
      }
  
      public string GetKodKreskowy()
      {
          return Osom.Enums.GetDescriptionFromEnumValue(Enum.Parse(Osom.MyType.GetTypeByName("AllProducts")[0], this.GetType().Name) as Enum)
              + " # " + Producent
              + " # " + NameProduct
              + " # " + Cena;
      }
  
  
      #region INTERFACE IMPLEMENTATION INotifyPropertyChanged
      protected void OnPropertyChanged(string propertyName)
      {
          if (PropertyChanged != null)
          {
              PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
          }
      }
  
      public event PropertyChangedEventHandler PropertyChanged;
      #endregion
  }
  </code></pre>
  
  <p>And Conteiner of this elements:</p>
  
  <pre><code>public class ProduktCointeiners
  {
      /*
      protected List&lt;Produkt&gt; lista = new List&lt;Produkt&gt;();
  
      public List&lt;Produkt&gt; Lista
      {
          get { return lista; }
      }*/
  
      public Dictionary&lt;string, Produkt&gt; dictionary = new Dictionary&lt;string, Produkt&gt;();
      ObservableCollection&lt;Produkt&gt; obserwator;
  
      public List&lt;Produkt&gt; ToList
      {
          get {
              return dictionary.Values.ToList();
          }
          set
          {
              dictionary.Clear();
              foreach (Produkt prod in value)
              {
                  dictionary.Add(prod.KodKreskowy, prod);
              }
          }
      }
  
  
      // Get Inne Prod
      #region Destroy Item
  
      /// &lt;summary&gt;
      /// Usuwa permamentnie element ze słownika
      /// &lt;/summary&gt;
      public void DestroyProduct(Produkt product)
      {
          DestroyProduct(product.KodKreskowy);
      }
  
      /// &lt;summary&gt;
      /// Usuwa permamentnie element ze słownika
      /// &lt;/summary&gt;
      public void DestroyProduct(string KodKreskowy)
      {
          for (int i = 0; i &lt; dictionary.Count; i++)
          {
  
              dictionary.Remove(KodKreskowy);
  
          }
      }
  
      #endregion
  
  
      #region Remove
  
      public void RemoveProduct(Produkt product)
      {
          RemoveProduct(product.KodKreskowy, product.Ilosc);
      }
  
  
      public void RemoveProduct(string KodKreskowy, int Ilosc)
      {
          foreach (Produkt prod in dictionary.Values)
          {
              if (prod.KodKreskowy == KodKreskowy)
              {
                  prod.Ilosc -= Ilosc;
                  return;
              }
          }
      }
  
      #endregion
  
  
  
      #region Add
      public void AddProduct(Produkt product)
      {
  
          try 
          {
  
              dictionary[product.KodKreskowy].Ilosc += product.Ilosc;
              if (dictionary[product.KodKreskowy].Cena &lt; product.Cena)
                  dictionary[product.KodKreskowy].Cena = product.Cena;
  
  
          }
          catch(KeyNotFoundException)
          {
              dictionary.Add(product.KodKreskowy, product);
              return;
          }
      }
  
      #endregion
  
  
  
      #region Cena
  
  
      public void ChangeCost(string KodKreskowy, double Cena)
      {
          dictionary[KodKreskowy].Cena = Cena;
      }
  
  
      public void ChangeCost(Produkt product)
      {
          ChangeCost(product.KodKreskowy, product.Cena);
      }
  
  
  
  
      #endregion
  
  
  
      #region Ilosc
  
      public void Ilosc_zwieksz(Produkt product)
      {
          Ilosc_zwieksz(product.KodKreskowy, product.Ilosc);
      }
  
  
      public void Ilosc_zwieksz(string KodKreskowy, int Ilosc)
      {
          dictionary[KodKreskowy].Ilosc += Ilosc;
      }
  
  
      public void Ilosc_zmniejsz(Produkt product)
      {
          Ilosc_zmniejsz(product.KodKreskowy, product.Ilosc);
      }
  
  
      public void Ilosc_zmniejsz(string KodKreskowy, int Ilosc)
      {
  
          dictionary[KodKreskowy].Ilosc -= Ilosc;
          if (dictionary[KodKreskowy].Ilosc &lt; 0)
          {
              MessageBox.Show("yyy... w Magazynie masz UJEMNE ilości przedmiotów! :D\n POZDRO!\nP.S. wartosc została zmieniona na 0");
              dictionary[KodKreskowy].Ilosc = 0;
          }
  
      }
  
      #endregion
  
      //#region INTERFACE IMPLEMENTATION INotifyPropertyChanged
      //protected void OnPropertyChanged(string propertyName)
      //{
      //    if (PropertyChanged != null)
      //    {
      //        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
      //    }
      //}
  
      //public event PropertyChangedEventHandler PropertyChanged;
      //#endregion
  
  
  
  }
  </code></pre>
  
  <p>And GUI (WPF code):</p>
  
  <pre><code>&lt;Window x:Class="Firma.View.MainWindow"
          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
          xmlns:controls="clr-namespace:Firma.View.MyControls"
          xmlns:converters="clr-namespace:Firma.View.Converters"
  
  
          Title="MainWindow" MinHeight="700" Height="700" MinWidth="800" Width="800" FontFamily="Comic Sans" FontSize="15" &gt;
      &lt;Window.Resources&gt;
          &lt;CollectionViewSource x:Key="ItemCollectionViewSource" CollectionViewType="ListCollectionView"/&gt;
          &lt;converters:ToCostConverter x:Key="ToCostConverter" /&gt;
          &lt;converters:BoolToVisibilityCollapsed x:Key="BoolToVisibilityCollapsed" /&gt;
      &lt;/Window.Resources&gt;
  
  
      &lt;Grid Margin="5"&gt;
          &lt;Grid.RowDefinitions&gt;
              &lt;RowDefinition Height="1*"/&gt;
              &lt;RowDefinition Height="1*"/&gt;
          &lt;/Grid.RowDefinitions&gt;
  
          &lt;!--MAGAZYN--&gt;
          &lt;GroupBox Grid.Row="0" Padding="3"&gt;         
              &lt;GroupBox.Header&gt;
                  &lt;TextBlock FontSize="20"&gt;Magazyn&lt;/TextBlock&gt;
              &lt;/GroupBox.Header&gt;
              &lt;DockPanel Grid.Row="0"&gt;
                  &lt;TextBox Text="{Binding isPanelAdmin.ToString()}"&gt;&lt;/TextBox&gt;
  
  
                  &lt;!--DATAGRID MAGAZYN--&gt;
                  &lt;DataGrid DockPanel.Dock="Top" Height="Auto" Name="dg_Magazyn" Margin="10,0"
                            AutoGenerateColumns="False" 
                            ItemsSource="{Binding Source=magazyn.GetAktualnyMagazyn().dictionary.Values}" 
                            CanUserAddRows="False"
                            ScrollViewer.VerticalScrollBarVisibility="Visible"
                            SelectionUnit="FullRow" 
                            IsReadOnly="True"
                            &gt;
  
  
                      &lt;DataGrid.Columns&gt;
                          &lt;DataGridTextColumn Header="Producent" Width="5*" Binding="{Binding Producent}"/&gt;
                          &lt;DataGridTextColumn Header="Nazwa produktu" Width="5*" Binding="{Binding NameProduct}" /&gt;
                          &lt;DataGridTextColumn Header="Cena" Width="1*" Binding="{Binding Cena, Converter={StaticResource ToCostConverter}}" &gt;
                              &lt;DataGridTextColumn.ElementStyle&gt;
                                  &lt;Style TargetType="TextBlock"&gt;
                                      &lt;Setter Property="HorizontalAlignment" Value="Right" /&gt;
                                  &lt;/Style&gt;
                              &lt;/DataGridTextColumn.ElementStyle&gt;
                          &lt;/DataGridTextColumn&gt;
                          &lt;DataGridTextColumn Header="Ilość" Width="1*" Binding="{Binding Ilosc}"&gt;
                              &lt;DataGridTextColumn.ElementStyle&gt;
                                  &lt;Style TargetType="TextBlock"&gt;
                                      &lt;Setter Property="HorizontalAlignment" Value="Right" /&gt;
                                  &lt;/Style&gt;
                              &lt;/DataGridTextColumn.ElementStyle&gt;
                          &lt;/DataGridTextColumn&gt;
                      &lt;/DataGrid.Columns&gt;
  
  
                  &lt;/DataGrid&gt;
  
  
  
  
  
  
  
              &lt;/DockPanel&gt;
          &lt;/GroupBox&gt;
  
  
  
      &lt;/Grid&gt;
  
  
  
  
  &lt;/Window&gt;
  </code></pre>
  
  <p>And code-behind:</p>
  
  <pre><code>public partial class MainWindow 
  {
  
      public static Magazyn.AllMagazyny magazyny;
      public static Klient.Klient klient;
  
      public Historia.Historia historiaZakupowKlientow;
  
      public List&lt;Produkt&gt; testing = new List&lt;Produkt&gt;();
  
      public void InitializeData()
      {
          magazyny = new Magazyn.AllMagazyny(new Magazyn.Magazyn());
          klient = new Klient.Klient();
  
          historiaZakupowKlientow = new Historia.Historia();
  
  
          // Zmiana elementow na wszystkie z enuma
          cb_M_Type.Items.Clear();
          foreach (AllProducts typeProd in Enum.GetValues(typeof(AllProducts)))
          {
              cb_M_Type.Items.Add(Enums.GetDescriptionFromEnumValue(typeProd));
          }
  
  
          //CollectionViewSource itemCollectionViewSource;
          //itemCollectionViewSource = (CollectionViewSource)(FindResource("ItemCollectionViewSource"));
          //itemCollectionViewSource.Source = klient.ToList;
  
  
  
  
          TESTING_VALUES();
          for (int i = 0; i &lt; 100; i++)
          {
              testing.Add(new PapierosyBezFiltra("asd", "asd", 12.2, 3));
          }
  
          this.dg_Magazyn.ItemsSource = magazyny.GetAktualnyMagazyn().dictionary.Values;
          this.dg_Klient.ItemsSource = klient.dictionary.Values;
  
      }
  
  
  
  
      public void TESTING_VALUES()
      {
          magazyny.GetAktualnyMagazyn().AddProduct(new PapierosyBezFiltra("producent1", "prod1", 12.55, 11));
          magazyny.GetAktualnyMagazyn().AddProduct(new PapierosyFiltr_Smakowy("producent2", "prod2", 22.55, 11));
          //magazyny.GetAktualnyMagazyn().AddProduct(new PapierosyFiltr_Tytoniowy("producent3", "prod3", 33, 11));
          //magazyny.GetAktualnyMagazyn().AddProduct(new PapierosyBezFiltra("producent4", "prod4", 44, 11));
          //magazyny.GetAktualnyMagazyn().AddProduct(new PapierosyBezFiltra("producent4", "prod4", 44, 11));
          //magazyny.GetAktualnyMagazyn().AddProduct(new PapierosyBezFiltra("producent4", "prod4", 44, 11));
  
          //magazyny.GetAktualnyMagazyn().AddProduct(new PapierosyBezFiltra("producent4", "prod4", 55, 11));
  
          //for (int i = 0; i &lt; 10; i++)
          //{
          //    magazyny.GetAktualnyMagazyn().AddProduct(new PapierosyFiltr_Smakowy(i.ToString() + ". prod", "nazwa", 1.2 * i * i * i, i));
          //}
  
          Produkt tmp;
          foreach(Produkt prod in magazyny.GetAktualnyMagazyn().ToList)
          {
              tmp = (Produkt)prod.Clone();
              tmp.Ilosc = 1;
              klient.AddProduct(tmp);
          }
  
  
      }
  
  }
  </code></pre>
  
  <p>My problem:
   When i delete something in dictionary, dataGrid not refresh it... -.-
  I read something about ObservableCollection but i really don't know how it implement to my project.
  When I change for example <code>Cena</code> dataGrid normally update date in columns but not delete and add rows :(</p>
  
  <p>PS. Sory for my english :P  </p>