Передача данных связанного списка на сводную страницу?Windows Phone 7 - PullRequest
2 голосов
/ 08 августа 2011

У меня абсолютная головная боль, выясняющая это. Мне очень нужна помощь с этим.

У меня есть listbox, заполненный элементами, вызываемыми общедоступным классом RSS-канала static static void. Как только список заполняется элементами с привязкой к данным, я нажимаю на элемент, и он передает его на мою сводную страницу. Однако, когда я щелкаю влево или вправо, все, что я получаю, это одно и то же изображение. Это моя проблема, и я хотел бы, чтобы пользователь щелкнул левой кнопкой мыши и загрузил предыдущее изображение RSS. Я также хотел бы перейти к следующей картинке, если пользователь прокручивает вправо.

Сообщество оказывало помощь в предоставлении ссылок на некоторые вещи или высказывании об отказе от использования списка и т. Д. Однако, хотя я новичок во всем этом, я просто хотел бы получить конкретную помощь по коду, который мне нужен, чтобы достичь того, что я иметь в виду. В этом нет ничего личного - мне просто нужно взять с собой бабистепс, прежде чем начать заниматься другими вещами, о которых я понятия не имею.

Вот весь мой соответствующий код.

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 # Код сзади:

 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);
    }     
   }
  }

Как только список заполнен, я пытаюсь передать выбор пользователя на сводную страницу. Я хочу, чтобы это же изображение отображалось в сводке, а когда пользователь поворачивается влево или вправо, оно показывает предыдущее или следующее изображение в коллекции.

Pivot Page Я пытаюсь передать это, 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>

Класс обслуживания RSS называется:

 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));
     }
    }
  }

и, наконец, класс RSSItem:

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; }
    }
  }

Ответы [ 3 ]

1 голос
/ 17 августа 2011

Отказ от ответственности: я не думаю, что привязка такого количества элементов к элементу управления Pivot - это правильно.Ваш пробег может варьироваться, но я думаю, что более виртуализированное решение будет более эффективным.В моих тестах, похоже, все прошло нормально, но мой маленький голос говорит мне, что здесь есть драконы ...

Я воссоздал ваш проект в меру своих возможностей и сделал некоторые улучшения, чтобы получить егоделать то, что вы хотели.По сути, уловка заключалась в том, чтобы использовать ViewModel, которая использовалась как для главной страницы списка (UserSubmitted.xaml), так и для страницы с элементами Pivot (PivotPage1.xaml).Установив свойство DataContext на обеих страницах для одного и того же объекта, мы смогли связать оба списка с одним и тем же источником, что исключает необходимость что-либо передавать.

В App.xaml.cs:

public static ViewData ViewModel { get; private set; }

private void Application_Launching(object sender, LaunchingEventArgs e)
{
     // note: you should properly Tombstone this data to prevent unnecessary network access
     ViewModel = new ViewData();
}

Вот как определяется ViewData:

public class ViewData : INotifyPropertyChanged
{
    private string _FeedTitle;
    private RssItem _SelectedItem = null;
    private ObservableCollection<RssItem> _feedItems = new ObservableCollection<RssItem>();

    private const string MyRssfeed = "http://feeds.bbci.co.uk/news/rss.xml";

    public ViewData()
    {
        RssService.GetRssItems(
            MyRssfeed,
            (title, items) =>
            {
                App.Current.RootVisual.Dispatcher.BeginInvoke(() =>
                {
                    FeedTitle = title;
                    FeedItems = new ObservableCollection<RssItem>(items);
                });
            },
            (exception) =>
            {
                MessageBox.Show(exception.Message);
            },
            null);
    }

    public ObservableCollection<RssItem> FeedItems
    {
        get { return _feedItems; }
        set
        {
            if (_feedItems == value)
                return;
            _feedItems = value;
            NotifyPropertyChanged(this, new PropertyChangedEventArgs("FeedItems"));
        }
    }

    public string FeedTitle
    {
        get { return _FeedTitle; }
        set
        {
            if (_FeedTitle == value)
                return;
            _FeedTitle = value;
            NotifyPropertyChanged(this, new PropertyChangedEventArgs("FeedTitle"));
        }
    }

    public RssItem SelectedItem
    {
        get { return _SelectedItem; }
        set
        {
            if (_SelectedItem == value)
                return;
            _SelectedItem = value;
            NotifyPropertyChanged(this, new PropertyChangedEventArgs("SelectedItem"));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyPropertyChanged(object sender, PropertyChangedEventArgs args)
    {
        if (PropertyChanged != null)
            PropertyChanged(sender, args);
    }
}

Как только это установлено, относительно легко соединить обаСвойства контекста данных страницы для App.ViewModel.

Последним элементом была прокрутка и позиционирование выбранного элемента при навигации.Когда вы выбираете элемент на странице списка, свойство SelectedItem общей ViewModel привязывается к свойству SelectedItem в ListBox.После перехода на страницу сведений мы должны найти выбранный элемент в сводной панели и сделать его видимым:

public PivotPage1()
{
    InitializeComponent();
    Loaded += (sender, e) =>
        {
            this.DataContext = App.ViewModel;
            var selectedItem = App.ViewModel.SelectedItem;
            var pi = ItemPivot.Items.First(p => p == selectedItem);
            ItemPivot.SelectedItem = pi;
        };
}

Установка свойства SelectedItem элемента управления Pivot прокручивает сводную информацию до нужного элемента и делает его видимым.

Полный образец выложен на http://chriskoenig.net/upload/imaged.zip, если вы хотите увидеть его в действии.

0 голосов
/ 13 августа 2011

Попробуйте следующее для сводки (на основе кода Алекса)

<Pivot ItemsSource="{Binding items}" SelectedItem="{Binding SelectedFeed, Mode=TwoWay}">
    <Pivot.ItemTemplate>
            <DataTemplate>
                <Image Source="{Binding Url}"/>
            </DataTemplate>
        </Pivot.ItemTemplate>
</Pivot>

Предполагается, что на сводной странице DataContext имеется один и тот же объект "items", обеспечивающий доступ ко всем элементам ленты, и свойство SelectedFeed, которое (как упомянул Алекс) поддерживает INotifyPropertyChanged

0 голосов
/ 08 августа 2011

Если я вас правильно понял, вам нужно привязать список следующим образом:

<ListBox ItemsSource="{Binding items}" SelectedItem="{Binding SelectedFeed, Mode=TwoWay}" />

А затем связать Pivot таким же образом:

<Pivot ItemsSource="{Binding items}" SelectedItem="{Binding SelectedFeed, Mode=TwoWay}" />
...