I am having an absolute headache figuring this out. I badly need some help with this.
I have a listbox populated with items called with a public static void RSS feed class. Once the listbox populates with the databound items, I click on an item and it passes it through to my pivot page. However, when I flick left or right, all I get is the same image. That is my problem, and what I would like to have happen is if the user flicks left, it loads the previous RSS image. I would like it to also go to the next picture if the If the user scrolls right.
The community has been helpful in providing links to some things, or saying to not use the listbox, etc. However while I am new to all of this, I would just like concrete help with the code i have to achieve what I have in mind. It’s nothing personal — I just need to take babysteps with this before I get worked up with other things I have no clue about.
Here is all my relevant code.
Page 1 Xaml:
<ListBox x:Name="listbox" HorizontalContentAlignment="Stretch" ItemsSource="{Binding items}" SelectionChanged="listbox_SelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate>
<Image Stretch="Fill" Height="60" Width="85" Source="{Binding Url}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Page1 C# Code Behind:
namespace Imaged
{
public partial class UserSubmitted : PhoneApplicationPage
{
private const string Myrssfeed = "http://feeds.bbci.co.uk/news/rss.xml";
public UserSubmitted()
{
InitializeComponent();
//This next function calls the RSS service, and returns the (items) and binds it to
//{listbox.ItemsSource = items;}. I am unable to reference the count of the items, or
//the array of it for some reason? The images load once the page loads.
RssService.GetRssItems(Myrssfeed, (items) => { listbox.ItemsSource = items; }, (exception) => { MessageBox.Show(exception.Message); }, null);
}
}
}
Once the listbox fills I am now trying to pass the selection by the user to a pivot page. I want that same image to show up in the pivot, and when the user pivots left or right, it shows the previous image or next image in the collection.
The Pivot Page I am trying to pass this to, XAML:
<Grid x:Name="LayoutRoot" Background="Transparent">
<!--Pivot Control-->
<controls:Pivot Title="{Binding Title}">
<!--Pivot item one-->
<controls:PivotItem x:Name="item1">
<Image Source="{Binding Url}"/> <!--I take it this is causing the pics to be the same?-->
</controls:PivotItem>
<!--Pivot item two-->
<controls:PivotItem x:Name="item2">
<Image Source="{Binding Url}"/>
</controls:PivotItem>
<!--Pivot item three-->
<controls:PivotItem x:Name="item3">
<Image Source="{Binding Url}"/>
</controls:PivotItem>
</controls:Pivot>
</Grid>
The RSS Service Class being called:
namespace WindowsPhone.Helpers
{
public class RssService
{
public static void GetRssItems(string rssFeed, Action<IList<RssItem>> onGetRssItemsCompleted = null, Action<Exception> onError = null, Action onFinally = null)
{
WebClient webClient = new WebClient();
// register on download complete event
webClient.OpenReadCompleted += delegate(object sender, OpenReadCompletedEventArgs e)
{
try
{
// convert rss result to model
IList<RssItem> rssItems = new List<RssItem>();
Stream stream = e.Result;
XmlReader response = XmlReader.Create(stream);
{
SyndicationFeed feeds = SyndicationFeed.Load(response);
foreach (SyndicationItem f in feeds.Items)
{
RssItem rssItem = new RssItem(f.Title.Text, f.Summary.Text, f.PublishDate.ToString(), f.Links[0].Uri.AbsoluteUri);
rssItems.Add(rssItem);
}
}
// notify completed callback
if (onGetRssItemsCompleted != null)
{
onGetRssItemsCompleted(rssItems);
}
}
finally
{
// notify finally callback
if (onFinally != null)
{
onFinally();
}
}
};
webClient.OpenReadAsync(new Uri(rssFeed));
}
}
}
and finally the RSSItem Class:
namespace WindowsPhone.Helpers
{
public class RssItem
{
public RssItem(string title, string summary, string publishedDate, string url)
{
Title = title;
Summary = summary;
PublishedDate = publishedDate;
Url = url;
// Get plain text from html
PlainSummary = HttpUtility.HtmlDecode(Regex.Replace(summary, "<[^>]+?>", ""));
}
public string Title { get; set; }
public string Summary { get; set; }
public string PublishedDate { get; set; }
public string Url { get; set; }
public string PlainSummary { get; set; }
}
}
Disclaimer: I don’t think that binding this many items to a Pivot control is necessarily the right thing to do. Your mileage may vary, but I think a more virtualized solution would be more efficient. For my tests, it seemed to perform OK, but my little voice tells me that there be dragons here…
I recreated your project to the best of my ability and made some enhancements to get it to do what you wanted. Basically, the trick was using a ViewModel that was shared between both the main list page (UserSubmitted.xaml) and the page with the Pivot items on it (PivotPage1.xaml). By setting both page’s DataContext property to the same object, we were able to bind both lists to the same source, thus eliminating the need to pass anything around.
In App.xaml.cs:
Here is how ViewData is defined:
Once this is established, it’s relatively easy to wire up both page’s data context properties to App.ViewModel.
Last item was the scrolling and positioning of the selected item when navigating. When you select an item from the list page, the SelectedItem property of the shared ViewModel is bound to the SelectedItem property on the ListBox. After navigation to the details page, we have to find the selected item in the pivot and make it visible:
Setting the SelectedItem property of the Pivot control scrolls the pivot to the proper item and makes it visible.
The full sample is posted at http://chriskoenig.net/upload/imaged.zip if you want to see it in action.