title: Observable collection - CollectionChanged Binding
body: <p>During programming, I ran into the following questions:</p>
  
  <ol>
  <li><p>Does a observable collection implement a CollectionChanged event by itself? (Because of differentbooks refering to the fact that it does, but google shows otherwise)</p></li>
  <li><p>I have the following code, and I want my UI to update by binding (the code is for windowsPhone 7.1) Also, the binding works for single items in my observable collection, but when I try to add a new object to my collection, the CollectionChanged event doesn't fire.</p>
  
  <p>namespace Phone.lib.ViewModel
  {
      public class DeviceViewModel : ViewModelBase
      {</p>
  
  <pre><code>    DeviceModelInfo InfoList = new DeviceModelInfo();
  
      public DeviceViewModel()
      {
      }
  
      public DeviceViewModel(int index)
      {
          // Here I add a new item to the collection, But the ui only shows: Beckhoff, ver....
          InfoList.Add(new DeviceInfo("name1", "name2", "name3"));
      }        
  }
  
  public class DeviceModelInfo : ObservableCollection&lt;DeviceInfo&gt;
  {
      public DeviceModelInfo() : base()
      {
          Add(new DeviceInfo("Beckhoff", "Ver. 1A2B3C", "Stopped"));      
      }
  }
  
  public class DeviceInfo : ViewModelBase
  {
      private string devicename;
      private string deviceid;
      private string devicestatus;
  
      public DeviceInfo(string first, string second, string third)
      {
          devicename = first;
          deviceid = second;
          devicestatus = third;
      }
  
      public string DeviceName
      {
          get { return devicename; }
          set 
          { 
          devicename = value;
          RaisePropertyChanged("DeviceName");
          }
      }
  
      public string DeviceID
      {
          get { return deviceid; }
          set { deviceid = value; }
      }
  
      public string DeviceStatus
      {
          get { return devicestatus; }
          set { devicestatus = value; }
      }
  
  }
  </code></pre></li>
  </ol>
  
  <p>Note: The class inherits from viewmodel base wich has the Inotify changed interface in it.</p>
  
  <p>Code from my Xaml:</p>
  
  <pre><code>&lt;phone:PhoneApplicationPage 
  x:Class="WindowsPhone.View.Device_Page"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
  xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
  xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  xmlns:ViewModel="clr-namespace:Phone.lib.ViewModel;assembly=Phone.lib"
  FontFamily="{StaticResource PhoneFontFamilyNormal}"
  FontSize="{StaticResource PhoneFontSizeNormal}"
  Foreground="{StaticResource PhoneForegroundBrush}"
  SupportedOrientations="Portrait" Orientation="Portrait"
  mc:Ignorable="d" d:DesignHeight="768" d:DesignWidth="480"
  shell:SystemTray.IsVisible="True"&gt;
  
  &lt;!-- Static Resource area for binding --&gt;
  &lt;phone:PhoneApplicationPage.Resources&gt;
      &lt;ViewModel:DeviceModelInfo x:Key="deviceinfo"&gt;&lt;/ViewModel:DeviceModelInfo&gt;
      &lt;ViewModel:DeviceModelSensor x:Key="devicesensors"&gt;&lt;/ViewModel:DeviceModelSensor&gt;
      &lt;ViewModel:DeviceModelActuator x:Key="deviceactuators"&gt;&lt;/ViewModel:DeviceModelActuator&gt;
  &lt;/phone:PhoneApplicationPage.Resources&gt;
  
  &lt;!-- LayoutRoot is the root grid where all page content is placed--&gt;
  &lt;Grid x:Name="LayoutRoot" Background="Transparent"&gt;
      &lt;Grid.RowDefinitions&gt;
          &lt;RowDefinition Height="Auto"/&gt;
          &lt;RowDefinition Height="*"/&gt;
      &lt;/Grid.RowDefinitions&gt;
  
      &lt;!--TitlePanel contains the name of the application and page title--&gt;
      &lt;StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28"&gt;
          &lt;TextBlock x:Name="ApplicationTitle" Text="Kremer app" Style="{StaticResource PhoneTextNormalStyle}"/&gt;
      &lt;/StackPanel&gt;
  
      &lt;!--ContentPanel - place additional content here--&gt;
  
  
      &lt;Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"&gt;
          &lt;ListBox Height="100" HorizontalAlignment="Left" Margin="-4,6,0,0" Name="Device_ListBox" VerticalAlignment="Top" Width="460" ItemsSource="{Binding Source={StaticResource deviceinfo}}"&gt;
              &lt;ListBox.ItemTemplate&gt;
                  &lt;DataTemplate&gt;
                      &lt;StackPanel Margin="0,0,0,17" Width="432" Height="100"&gt;
                          &lt;TextBlock TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextExtraLargeStyle}" Text="{Binding Path=DeviceName, Mode=TwoWay}" /&gt;
                          &lt;TextBlock TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextSubtleStyle}" Text="{Binding Path=DeviceID, Mode=TwoWay}" /&gt;
                          &lt;TextBlock TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextSubtleStyle}" Text="{Binding Path=DeviceStatus, Mode=TwoWay}" /&gt;
                      &lt;/StackPanel&gt;
                  &lt;/DataTemplate&gt;
              &lt;/ListBox.ItemTemplate&gt;
          &lt;/ListBox&gt;
          &lt;ListBox Height="261" HorizontalAlignment="Left" Margin="-4,138,0,0" Name="Sensor_ListBox" VerticalAlignment="Top" Width="460" ItemsSource="{Binding Source={StaticResource devicesensors}}"&gt;
              &lt;ListBox.ItemTemplate&gt;
                  &lt;DataTemplate&gt;
                      &lt;StackPanel Margin="0,0,0,17" Width="432" Height="78"&gt;
                          &lt;TextBlock TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextExtraLargeStyle}" Text="{Binding Path=SensorName}" /&gt;
                          &lt;TextBlock TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextSubtleStyle}" Text="{Binding Path=SensorType}" /&gt;
                      &lt;/StackPanel&gt;
                  &lt;/DataTemplate&gt;
              &lt;/ListBox.ItemTemplate&gt;
          &lt;/ListBox&gt;
          &lt;ListBox Height="261" HorizontalAlignment="Left" Margin="-4,429,0,0" Name="Actuator_ListBox" ItemsSource="{Binding Source={StaticResource deviceactuators}}" VerticalAlignment="Top" Width="460"&gt;
              &lt;ListBox.ItemTemplate&gt;
                  &lt;DataTemplate&gt;
                      &lt;StackPanel Height="78" Margin="0,0,0,17" Width="432"&gt;
                          &lt;TextBlock Margin="12,-6,12,0" Style="{StaticResource PhoneTextExtraLargeStyle}" Text="{Binding Path=ActuatorName}" TextWrapping="Wrap" /&gt;
                          &lt;TextBlock Margin="12,-6,12,0" Style="{StaticResource PhoneTextSubtleStyle}" Text="{Binding Path=ActuatorType}" TextWrapping="Wrap" /&gt;
                      &lt;/StackPanel&gt;
                  &lt;/DataTemplate&gt;
              &lt;/ListBox.ItemTemplate&gt;
          &lt;/ListBox&gt;
      &lt;/Grid&gt;
  
  &lt;/Grid&gt;
  </code></pre>
  
  <p></p>
  
  <p>I hope someone is able to help me with this problem because i have been at this for like two days now.</p>
  
  <p>Also, my apologies for my "bad" english, but english is not my native language</p>
  
  <p>Cheers -Bart </p>
  
  <p>EDIT: done a little test </p>
  
  <p>I have run a little debugtest myself to see if the add operation adds to the right collection en therefor increments the count value</p>
  
  <pre><code>        public DeviceViewModel(int index)
          {
          // Here I add a new item to the collection, But the ui only shows: Beckhoff, ver....
  
          Debug.WriteLine("number of added items " + InfoList.Count.ToString());
          InfoList.Add(new DeviceInfo("1", "2", "3"));
          Debug.WriteLine("number of added items " + InfoList.Count.ToString());
          InfoList.Add(new DeviceInfo("1", "2", "3"));
          InfoList.Add(new DeviceInfo("1", "2", "3"));
          InfoList.Add(new DeviceInfo("1", "2", "3"));
          Debug.WriteLine("number of added items " + InfoList.Count.ToString());
          }  
  </code></pre>
  
  <p>output:</p>
  
  <p>number of added items 1</p>
  
  <p>number of added items 2</p>
  
  <p>number of added items 5</p>
  
  <p>Edit 2 (19-03-2012)</p>
  
  <p>Last friday I tried to get it working like you suggested. But somehow the XAML can't find InfoList, and I don't know why. Maybe I do something wrong in the XAML itself or in the code behind or in the DeviceViewModel. So here is what I have at the moment:</p>
  
  <p>DeviceViewModel:</p>
  
  <pre><code>namespace Phone.lib.ViewModel
  {
      public class DeviceViewModel : ViewModelBase
      {
  
          public DeviceModelInfo InfoList  = new DeviceModelInfo();
  
          public DeviceViewModel()
          {
              //DeviceModelInfo InfoList  = new DeviceModelInfo();
              InfoList.Add(new DeviceInfo("1", "2", "3"));
  
          }
  
          public DeviceViewModel(int index)
          {
  
          }
      }
  
      public class DeviceModelInfo : ObservableCollection&lt;DeviceInfo&gt;
      {
          public DeviceModelInfo() : base()
          {
              Add(new DeviceInfo("Beckhoff", "Ver. 1A2B3C", "Stopped"));
              //this.CollectionChanged += (e, s) =&gt; { Debug.WriteLine("event Fired " + e.ToString()); };
          }
  
      }
  
      public class DeviceInfo : ViewModelBase
      {
  
  
          private string devicename;
          private string deviceid;
          private string devicestatus;
  
          public DeviceInfo(string first, string second, string third)
          {
  
              devicename = first;
              deviceid = second;
              devicestatus = third;
  
          }
  
          public string DeviceName
          {
              get { return devicename; }
              set 
              { 
                  devicename = value;
                  RaisePropertyChanged("DeviceName");
              }
          }
  
          public string DeviceID
          {
              get { return deviceid; }
              set { deviceid = value; }
          }
  
          public string DeviceStatus
          { 
              get { return devicestatus; }
              set { devicestatus = value; }
          }
      }
  </code></pre>
  
  <p>The code behind the page:</p>
  
  <pre><code>namespace WindowsPhone.View
  {
      public partial class Device_Page : PhoneApplicationPage
      {
  
          private DeviceViewModel _DV;
  
          public Device_Page()
          {
  
              InitializeComponent();
              _DV = new DeviceViewModel();
              DataContext = _DV;
  
          }
  
          protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
          {
              string selectedIndex = "";
              if (NavigationContext.QueryString.TryGetValue("selectedItem", out selectedIndex))
              {
                  int index = int.Parse(selectedIndex);
  
                  //_DV = new DeviceViewModel(index);
                  //DataContext = _DV;
  
                  Debug.WriteLine("index:" + index.ToString());
              }
          }
  
      }
  }
  </code></pre>
  
  <p>The XAML code:</p>
  
  <pre><code>&lt;phone:PhoneApplicationPage 
  x:Class="WindowsPhone.View.Device_Page"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
  xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
  xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  xmlns:ViewModel="clr-namespace:Phone.lib.ViewModel;assembly=Phone.lib"
  FontFamily="{StaticResource PhoneFontFamilyNormal}"
  FontSize="{StaticResource PhoneFontSizeNormal}"
  Foreground="{StaticResource PhoneForegroundBrush}"
  SupportedOrientations="Portrait" Orientation="Portrait"
  mc:Ignorable="d" d:DesignHeight="768" d:DesignWidth="480"
  shell:SystemTray.IsVisible="True"&gt;
  
  
  &lt;!-- Static Resource area for binding --&gt;
  &lt;phone:PhoneApplicationPage.Resources&gt;
      &lt;ViewModel:DeviceViewModel x:Key="deviceinfo"&gt;&lt;/ViewModel:DeviceViewModel&gt;
      &lt;ViewModel:DeviceModelSensor x:Key="devicesensors"&gt;&lt;/ViewModel:DeviceModelSensor&gt;
      &lt;ViewModel:DeviceModelActuator x:Key="deviceactuators"&gt;&lt;/ViewModel:DeviceModelActuator&gt;
  &lt;/phone:PhoneApplicationPage.Resources&gt;
  
  &lt;!-- LayoutRoot is the root grid where all page content is placed--&gt;
  &lt;Grid x:Name="LayoutRoot" Background="Transparent"&gt;
      &lt;Grid.RowDefinitions&gt;
          &lt;RowDefinition Height="Auto"/&gt;
          &lt;RowDefinition Height="*"/&gt;
      &lt;/Grid.RowDefinitions&gt;
  
      &lt;!--TitlePanel contains the name of the application and page title--&gt;
      &lt;StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28"&gt;
          &lt;TextBlock x:Name="ApplicationTitle" Text="Kremer app" Style="{StaticResource PhoneTextNormalStyle}"/&gt;
      &lt;/StackPanel&gt;
  
      &lt;!--ContentPanel - place additional content here--&gt;
      &lt;Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"&gt;
          &lt;ListBox Height="100" HorizontalAlignment="Left" Margin="-4,6,0,0" Name="Device_ListBox" VerticalAlignment="Top" Width="460" ItemsSource="{Binding InfoList}"&gt;
              &lt;ListBox.ItemTemplate&gt;
                  &lt;DataTemplate&gt;
                      &lt;StackPanel Margin="0,0,0,17" Width="432" Height="100"&gt;
                          &lt;TextBlock TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextExtraLargeStyle}" Text="{Binding Path=DeviceName, Mode=TwoWay}" /&gt;
                          &lt;TextBlock TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextSubtleStyle}" Text="{Binding Path=DeviceID, Mode=TwoWay}" /&gt;
                          &lt;TextBlock TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextSubtleStyle}" Text="{Binding Path=DeviceStatus, Mode=TwoWay}" /&gt;
                      &lt;/StackPanel&gt;
                  &lt;/DataTemplate&gt;
              &lt;/ListBox.ItemTemplate&gt;
          &lt;/ListBox&gt;
          &lt;ListBox Height="261" HorizontalAlignment="Left" Margin="-4,138,0,0" Name="Sensor_ListBox" VerticalAlignment="Top" Width="460" ItemsSource="{Binding Source={StaticResource devicesensors}}"&gt;
              &lt;ListBox.ItemTemplate&gt;
                  &lt;DataTemplate&gt;
                      &lt;StackPanel Margin="0,0,0,17" Width="432" Height="78"&gt;
                          &lt;TextBlock TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextExtraLargeStyle}" Text="{Binding Path=SensorName}" /&gt;
                          &lt;TextBlock TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextSubtleStyle}" Text="{Binding Path=SensorType}" /&gt;
                      &lt;/StackPanel&gt;
                  &lt;/DataTemplate&gt;
              &lt;/ListBox.ItemTemplate&gt;
          &lt;/ListBox&gt;
          &lt;ListBox Height="261" HorizontalAlignment="Left" Margin="-4,429,0,0" Name="Actuator_ListBox" ItemsSource="{Binding Source={StaticResource deviceactuators}}" VerticalAlignment="Top" Width="460"&gt;
              &lt;ListBox.ItemTemplate&gt;
                  &lt;DataTemplate&gt;
                      &lt;StackPanel Height="78" Margin="0,0,0,17" Width="432"&gt;
                          &lt;TextBlock Margin="12,-6,12,0" Style="{StaticResource PhoneTextExtraLargeStyle}" Text="{Binding Path=ActuatorName}" TextWrapping="Wrap" /&gt;
                          &lt;TextBlock Margin="12,-6,12,0" Style="{StaticResource PhoneTextSubtleStyle}" Text="{Binding Path=ActuatorType}" TextWrapping="Wrap" /&gt;
                      &lt;/StackPanel&gt;
                  &lt;/DataTemplate&gt;
              &lt;/ListBox.ItemTemplate&gt;
          &lt;/ListBox&gt;
      &lt;/Grid&gt;
  
  &lt;/Grid&gt;
  
  
  
  &lt;/phone:PhoneApplicationPage&gt;
  </code></pre>