我正在尝试实现一个"无限"列表框,每次到达列表框末尾时都会加载新数据。当我尝试反序列化下一组搜索结果时出现问题。我正在Operation not supported on read-only collection
.
这是我的课程。
public class Search
{
//public Spellcheck spellcheck { get; set; }
public ObservableCollection<ResultSearch> results = new ObservableCollection<ResultSearch>();
public IEnumerator<ResultSearch> 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<SearchArtist> artists { get; set; }
public List<SearchGenre> genres { get; set; }
public List<object> subGenres { get; set; }
public List<SearchChart> 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; }
}
反序列化新数据
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 <= 5)
{
// WebClient jsonSearch
WebClient jsonSearch = new GzipWebClient();
Uri apiSearch = new Uri("http://api.beatport.com/catalog/3/search?query=" + searchTxtBox.Text + "&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<Search>(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<Search>(e.Result);
//listSearch.Items.Add(searchDataPage.results);
}
感谢您的帮助。
更新
这也是我的xaml
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<ListBox x:Name="listSearch" >
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" >
<Image delay:LowProfileImageLoader.UriSource="{Binding images.medium.url}" Tap="searchSelectedImageHandler" Margin="10" Width="60" Height="60" />
<StackPanel Orientation="Vertical" >
<TextBlock Text="{Binding name}" Tap="searchSelectedHandler" Style="{StaticResource PhoneTextLargeStyle}"/>
<TextBlock Text="{Binding type}" Style="{StaticResource PhoneTextSubtleStyle}" />
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
发布的代码有一个带有ObservableCollection
的class Search
:
public ObservableCollection<ResultSearch> results = new ObservableCollection<ResultSearch>();
但是,反序列化正在尝试添加到listSearch
:
listSearch.Items.Add(searchDataPage.results);
我怀疑,这些项目应该添加到results
集合中,而不是listSearch
控件中。
编辑以回复评论:
这里要做的最快(不是最理想)的事情是在代码隐藏中创建可观察集合,然后将列表框的 ItemsSource 设置为 ObservableCollection 并修改 json 方法:
// code behind for your xaml
public partial class MyCodeBehind
{
public ObservableCollection<Search> Searches;
public MyCodeBehind()
{
InitializeComponent();
Searches = new ObservableCollection<Search>();
// bind the collection to the ListBox
this.listSearch.ItemsSource = Searches;
}
// Deserialize search json data
public void jsonSearch_GetDataCompleted(object sender, DownloadStringCompletedEventArgs e)
{
Search searchData = JsonConvert.DeserializeObject<Search>(e.Result);
if (searchData.results.Count == 0)
{
MessageBox.Show("your search didn't return any results");
}
else
{
// add the results to the existing Searches collection
foreach (Search search in searchData.results)
{
Searches.Add(search);
}
}
}
// Deserialize search next page json data
public void jsonSearchNextPage_GetDataCompleted(object sender, DownloadStringCompletedEventArgs e)
{
Search searchDataPage = JsonConvert.DeserializeObject<Search>(e.Result);
// add the results to the existing Searches collection
foreach (Search search in searchDataPage)
{
Searches.Add(search);
}
}
}