title: WP7 Adding data to infinite listbox
body: <p>I'm trying to implement an "infinite" listbox that will load new data each time the end of listbox is reached. Issue occurs when I try to deserialize the next set of search results. I'm getting a <code>Operation not supported on read-only collection</code>.</p>
  
  <p>Here are my classes.</p>
  
  <pre><code>public class Search
  {
      //public Spellcheck spellcheck { get; set; }
      public ObservableCollection&lt;ResultSearch&gt; results = new ObservableCollection&lt;ResultSearch&gt;();
  
      public IEnumerator&lt;ResultSearch&gt; GetEnumerator()
      {
          return this.results.GetEnumerator();
      }
  }
  
  public class ResultSearch
  {
      public int id { get; set; }
      public bool selected { get; set; }
      public string type { get; set; }
      public string name { get; set; }
      public bool active { get; set; }
      public string mixName { get; set; }
      public string title { get; set; }
      public string slug { get; set; }
      public object isrc { get; set; }
      public string releaseDate { get; set; }
      public string publishDate { get; set; }
      public string sampleUrl { get; set; }
      public string rtmpStreamUrl { get; set; }
      public bool exclusive { get; set; }
      public Price price { get; set; }
      //public AudioFormatFee audioFormatFee { get; set; }
      public string currentStatus { get; set; }
      public string length { get; set; }
      public int bpm { get; set; }
      public Key key { get; set; }
      public string saleType { get; set; }
      public List&lt;SearchArtist&gt; artists { get; set; }
      public List&lt;SearchGenre&gt; genres { get; set; }
      public List&lt;object&gt; subGenres { get; set; }
      public List&lt;SearchChart&gt; charts { get; set; }
      public SearchRelease release { get; set; }
      public SearchLabel label { get; set; }
      public SearchImages images { get; set; }
      //public DynamicImages dynamicImages { get; set; }
      public string bio { get; set; }
      public string url { get; set; }
  }
  
  public class SearchArtist
  {
      public int id { get; set; }
      public string name { get; set; }
      public string slug { get; set; }
      public string type { get; set; }
  }
  
  public class SearchGenre
  {
      public int id { get; set; }
      public string name { get; set; }
      public string slug { get; set; }
      public string type { get; set; }
  }
  
  public class SearchChart
  {
      public int id { get; set; }
      public int position { get; set; }
      public string type { get; set; }
  }
  
  public class SearchRelease
  {
      public int id { get; set; }
      public string name { get; set; }
      public string type { get; set; }
      public string slug { get; set; }
  }
  
  public class SearchLabel
  {
      public int id { get; set; }
      public string name { get; set; }
      public string type { get; set; }
      public string slug { get; set; }
  }
  
  public class SearchImages
  {
      //public Small small { get; set; }
      //public SearchMedium medium { get; set; }
      public SearchLarge large { get; set; }
      //public SearchBanner banner { get; set; }
      //public Waveform waveform { get; set; }
  }
  
  public class SearchLarge
  {
      public int width { get; set; }
      public int height { get; set; }
      public string url { get; set; }
      public string secureUrl { get; set; }
  }
  </code></pre>
  
  <p>Deserializing the new data</p>
  
  <pre><code>protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
      {
          base.OnNavigatedTo(e);
  
          string searchTxt = String.Empty;
          if (NavigationContext.QueryString.TryGetValue("searchTxt", out searchTxt))
          {
              searchTxtBox.Text = searchTxt;
              HttpUtility.UrlEncode(searchTxt);
              LaunchWebClient(searchTxt);
          }
      }
  
      private void LaunchWebClient(string searchTxt)
      {
          // WebClient jsonSearch
          WebClient jsonSearch = new GzipWebClient();
          Uri apiSearch = new Uri("http://api.beatport.com/catalog/3/search?query=" + searchTxt);
          jsonSearch.DownloadStringCompleted += new DownloadStringCompletedEventHandler(jsonSearch_GetDataCompleted);
          jsonSearch.DownloadStringAsync(apiSearch);
      }
  
      // When end of listbox is reached
      private void LaunchWebClientNextpage(int page)
      {
          int pageLimit = page;
          if (pageLimit &lt;= 5)
          {
              // WebClient jsonSearch
              WebClient jsonSearch = new GzipWebClient();
              Uri apiSearch = new Uri("http://api.beatport.com/catalog/3/search?query=" + searchTxtBox.Text + "&amp;page=" + page);
              jsonSearch.DownloadStringCompleted += new DownloadStringCompletedEventHandler(jsonSearchNextPage_GetDataCompleted);
              jsonSearch.DownloadStringAsync(apiSearch);
          }
          else
          {
              SystemTray.SetIsVisible(this, false);
              //SystemTray.SetOpacity(this, 0.0);
              prog.IsVisible = false;
              prog.IsIndeterminate = false;
          }
      }
  
      // Deserialize search json data
      public void jsonSearch_GetDataCompleted(object sender, DownloadStringCompletedEventArgs e)
      {
          Search searchData = JsonConvert.DeserializeObject&lt;Search&gt;(e.Result);
  
          if (searchData.results.Count == 0)
          {
              MessageBox.Show("your search didn't return any results");
          }
          else
          {
              this.listSearch.ItemsSource = searchData.results;
          }
      }
  
      // Deserialize search next page json data
      public void jsonSearchNextPage_GetDataCompleted(object sender, DownloadStringCompletedEventArgs e)
      {
          Search searchDataPage = JsonConvert.DeserializeObject&lt;Search&gt;(e.Result);
  
          //listSearch.Items.Add(searchDataPage.results);
      }
  </code></pre>
  
  <p>Thanks for the help.</p>
  
  <p><strong>UPDATE</strong></p>
  
  <p>Here is my xaml as well</p>
  
  <pre><code>&lt;!--ContentPanel - place additional content here--&gt;
      &lt;Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"&gt;            
          &lt;ListBox x:Name="listSearch" &gt;
              &lt;ListBox.ItemTemplate&gt;
                  &lt;DataTemplate&gt;
                      &lt;StackPanel Orientation="Horizontal" &gt;
                          &lt;Image delay:LowProfileImageLoader.UriSource="{Binding images.medium.url}" Tap="searchSelectedImageHandler" Margin="10" Width="60" Height="60" /&gt;
                          &lt;StackPanel Orientation="Vertical" &gt;
                              &lt;TextBlock Text="{Binding name}" Tap="searchSelectedHandler" Style="{StaticResource PhoneTextLargeStyle}"/&gt;
                              &lt;TextBlock Text="{Binding type}" Style="{StaticResource PhoneTextSubtleStyle}" /&gt;
                          &lt;/StackPanel&gt;
                      &lt;/StackPanel&gt;
                  &lt;/DataTemplate&gt;
              &lt;/ListBox.ItemTemplate&gt;
          &lt;/ListBox&gt;
      &lt;/Grid&gt;
  </code></pre>