0
  1. Чтобы получить данные из сети и отображения
  2. Я использую LongListSelector (articleList) для отображения данных, веб-интерфейс API работы, уже прошла проверку в визуальной студии, установив точку останова.
  3. [ISSUE] установка ItemSource для просмотраModel.ArticleCollection, после извлечения данных из веб-api, LongListSelector не обновляется.
  4. , но после кода chenge в методе OnNavigatedTo в MainPage.xaml.cs, FROM "_viewModel.LoadPage (_searchTerm, _pageNumber ++);" TO "articleList.ItemsSource = ожидание CollectionHttpClient.GetAllArticlesAsync();" IT ОТОБРАЖАЕТ данные веб-api.

Кто-нибудь может мне помочь? заранее спасибо!LongListSelector не обновляется после связывания с ItemsSource

MainPage.xaml

<phone:PhoneApplicationPage 
x:Class="CollectionApp.MainPage" 
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:vm="clr-namespace:CollectionApp.ViewModels" 
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
mc:Ignorable="d" 

FontFamily="{StaticResource PhoneFontFamilyNormal}" 
FontSize="{StaticResource PhoneFontSizeNormal}" 
Foreground="{StaticResource PhoneForegroundBrush}" 
SupportedOrientations="Portrait" Orientation="Portrait" 
shell:SystemTray.IsVisible="True"> 

<phone:PhoneApplicationPage.Resources> 

    <vm:ArticleListViewModel x:Key="viewModel"/> 

    <DataTemplate x:Key="ResultItemTemplate"> 
     <Grid Margin="0,6,0,0"> 
      <Grid.RowDefinitions> 
       <RowDefinition Height="Auto"/> 
       <RowDefinition Height="*"/> 
      </Grid.RowDefinitions> 
      <Grid.ColumnDefinitions> 
       <ColumnDefinition Width="Auto"/> 
       <ColumnDefinition Width="*"/> 
      </Grid.ColumnDefinitions> 
      <Rectangle Fill="Gray" Height="50" Width="50" Grid.Row="0" Grid.Column="0" 
        VerticalAlignment="Top" Margin="0,7,7,0" 
        Grid.RowSpan="2"> 

      </Rectangle> 
      <Image Height="50" Width="50" Grid.Row="0" Grid.Column="0" 
        VerticalAlignment="Top" Margin="0,7,7,0" 
        Grid.RowSpan="2"> 
       <Image.Source> 
        <BitmapImage UriSource="{Binding ImagePath}" 
           CreateOptions="BackgroundCreation"/> 
       </Image.Source> 
      </Image> 
      <TextBlock Text="{Binding Subject}" Grid.Row="0" Grid.Column="1" 
          Foreground="{StaticResource PhoneAccentBrush}" VerticalAlignment="Top"/> 

      <TextBlock Text="{Binding Words}" TextWrapping="Wrap" 
          Grid.Row="1" Grid.Column="1" 
          VerticalAlignment="Top" 
          /> 

     </Grid> 
    </DataTemplate> 

</phone:PhoneApplicationPage.Resources> 

<!--LayoutRoot is the root grid where all page content is placed--> 
<Grid x:Name="LayoutRoot" Background="Transparent"> 

    <!-- LOCALIZATION NOTE: 
     To localize the displayed strings copy their values to appropriately named 
     keys in the app's neutral language resource file (AppResources.resx) then 
     replace the hard-coded text value between the attributes' quotation marks 
     with the binding clause whose path points to that string name. 

     For example: 

      Text="{Binding Path=LocalizedResources.ApplicationTitle, Source={StaticResource LocalizedStrings}}" 

     This binding points to the template's string resource named "ApplicationTitle". 

     Adding supported languages in the Project Properties tab will create a 
     new resx file per language that can carry the translated values of your 
     UI strings. The binding in these examples will cause the value of the 
     attributes to be drawn from the .resx file that matches the 
     CurrentUICulture of the app at run time. 
    --> 

    <!--Pivot Control--> 
    <phone:Pivot Title="{Binding Path=LocalizedResources.ApplicationTitle, Source={StaticResource LocalizedStrings}}"> 
     <!--Pivot item one--> 
     <phone:PivotItem Header="Articles"> 
      <!--Double line list with text wrapping--> 
      <phone:LongListSelector 
       x:Name="articleList" 
       Grid.Row="1" 
       Margin="0,0,-12,0" 
       DataContext="{StaticResource viewModel}" 
       ItemTemplate="{StaticResource ResultItemTemplate}" 
       ItemsSource="{Binding viewModel.ArticleCollection}" 
       > 

      </phone:LongListSelector> 
     </phone:PivotItem> 

     <!--Pivot item two--> 
     <phone:PivotItem Header="second"> 
      <!--Double line list no text wrapping--> 
      <phone:LongListSelector Margin="0,0,-12,0" ItemsSource="{Binding Items}"> 
       <phone:LongListSelector.ItemTemplate> 
         <DataTemplate> 
          <StackPanel Margin="0,0,0,17"> 
           <TextBlock Text="{Binding LineOne}" TextWrapping="NoWrap" Margin="12,0,0,0" Style="{StaticResource PhoneTextExtraLargeStyle}"/> 
           <TextBlock Text="{Binding LineThree}" TextWrapping="NoWrap" Margin="12,-6,0,0" Style="{StaticResource PhoneTextSubtleStyle}"/> 
          </StackPanel> 
         </DataTemplate> 
       </phone:LongListSelector.ItemTemplate> 
      </phone:LongListSelector> 
     </phone:PivotItem> 
    </phone:Pivot> 

    <!--Uncomment to see an alignment grid to help ensure your controls are 
     aligned on common boundaries. The image has a top margin of -32px to 
     account for the System Tray. Set this to 0 (or remove the margin altogether) 
     if the System Tray is hidden. 

     Before shipping remove this XAML and the image itself.--> 
    <!--<Image Source="/Assets/AlignmentGrid.png" VerticalAlignment="Top" Height="800" Width="480" Margin="0,-32,0,0" Grid.Row="0" IsHitTestVisible="False" />--> 
</Grid> 

</phone:PhoneApplicationPage> 

MainPage.xaml.cs

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Net; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Navigation; 
using Microsoft.Phone.Controls; 
using Microsoft.Phone.Shell; 
using CollectionApp.Resources; 
using CollectionApp.Network; 
using CollectionApp.Models; 
using CollectionApp.ViewModels; 
using System.Windows.Data; 
using System.Diagnostics; 
using Windows.UI.Core; 

namespace CollectionApp 
{ 
    public partial class MainPage : PhoneApplicationPage 
    { 
     int _pageNumber = 1; 
     string _searchTerm = ""; 
     ArticleListViewModel _viewModel = new ArticleListViewModel(); 
     int _offsetKnob = 1; 

     // Constructor 
     public MainPage() 
     { 
      InitializeComponent(); 

      //_viewModel = new ArticleListViewModel(); 
      _viewModel = (ArticleListViewModel)Resources["viewModel"]; 
      DataContext = _viewModel; 

      articleList.ItemRealized += articleList_ItemRealized; 
      this.Loaded += new RoutedEventHandler(MainPage_Loaded); 

      //_viewModel = new ArticleListViewModel(); 
      articleList.ItemsSource = _viewModel.ArticleCollection; 

      // Set the data context of the listbox control to the sample data 
      //DataContext = App.ViewModel; 

      // Sample code to localize the ApplicationBar 
      //BuildLocalizedApplicationBar(); 
     } 

     void MainPage_Loaded(object sender, RoutedEventArgs e) 
     { 
      var progressIndicator = SystemTray.ProgressIndicator; 
      if(progressIndicator != null) 
      { 
       return; 
      } 

      progressIndicator = new ProgressIndicator(); 

      SystemTray.SetProgressIndicator(this, progressIndicator); 

      Binding binding = new Binding("IsLoading") { Source = _viewModel }; 
      BindingOperations.SetBinding(progressIndicator, ProgressIndicator.IsVisibleProperty, binding); 

      binding = new Binding("IsLoading") { Source = _viewModel}; 
      BindingOperations.SetBinding(progressIndicator, ProgressIndicator.IsIndeterminateProperty, binding); 

      progressIndicator.Text = "Loading new Articles....";    

     } 

     private void articleList_ItemRealized(object sender, ItemRealizationEventArgs e) 
     { 
      if (!_viewModel.IsLoading && articleList.ItemsSource != null && articleList.ItemsSource.Count >= _offsetKnob) 
      { 
       if (e.ItemKind == LongListSelectorItemKind.Item) 
       { 
        if ((e.Container.Content as Article).Equals(articleList.ItemsSource[articleList.ItemsSource.Count - _offsetKnob])) 
        { 
         Debug.WriteLine("Searching for {0}", _pageNumber); 
         //_viewModel.LoadPage(_searchTerm, _pageNumber++); 
        } 
       } 
      } 
     } 


     // Load data for the ViewModel Items 
     protected async override void OnNavigatedTo(NavigationEventArgs e) 
     { 
      try 
      { 
       if (CollectionHttpClient.IsDirty) 
       { 
        _viewModel.LoadPage(_searchTerm, _pageNumber++); 
        // articleList.ItemsSource = await CollectionHttpClient.GetAllArticlesAsync(); ; 

       } 
      } 
      catch 
      { 
       MessageBox.Show("sorry, no data."); 
      } 
     } 

     // Sample code for building a localized ApplicationBar 
     //private void BuildLocalizedApplicationBar() 
     //{ 
     // // Set the page's ApplicationBar to a new instance of ApplicationBar. 
     // ApplicationBar = new ApplicationBar(); 

     // // Create a new button and set the text value to the localized string from AppResources. 
     // ApplicationBarIconButton appBarButton = new ApplicationBarIconButton(new Uri("/Assets/AppBar/appbar.add.rest.png", UriKind.Relative)); 
     // appBarButton.Text = AppResources.AppBarButtonText; 
     // ApplicationBar.Buttons.Add(appBarButton); 

     // // Create a new menu item with the localized string from AppResources. 
     // ApplicationBarMenuItem appBarMenuItem = new ApplicationBarMenuItem(AppResources.AppBarMenuItemText); 
     // ApplicationBar.MenuItems.Add(appBarMenuItem); 
     //} 

     private void LongListSelector_SelectionChanged(object sender, SelectionChangedEventArgs e) 
     { 
      LongListSelector selector = sender as LongListSelector; 

      // verifying sender is actually a LongListSelector 
      if (selector == null) 
      { 
       return; 
      } 

      NavigationService.Navigate(new Uri("Pages/DetailsPage.xaml?id=" + (selector.SelectedItem as Article).ID, UriKind.RelativeOrAbsolute)); 

      // 
      selector.SelectedItem = null; 

     } 


    } 
} 

ArticleListViewModel.cs

using CollectionApp.Models; 
using CollectionApp.Network; 
using System; 
using System.Collections.Generic; 
using System.Collections.ObjectModel; 
using System.ComponentModel; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows; 

namespace CollectionApp.ViewModels 
{ 
    public class ArticleListViewModel : INotifyPropertyChanged 
    { 
     private bool _isLoading = false; 

     public bool IsLoading 
     { 
      get 
      { 
       return _isLoading; 
      } 
      set 
      { 
       _isLoading = value; 
       NotifyPropertyChanged("IsLoading"); 
      } 
     } 

     public ArticleListViewModel() 
     { 
      this.ArticleCollection = new ObservableCollection<Article>(); 
      this.IsLoading = false; 
     } 


     public ObservableCollection<Article> ArticleCollection 
     { 
      get; 
      private set; 
     } 

     public void LoadPage(string searchTerm, int pageNumber) 
     { 
      if (pageNumber == 1) 
      { 
       this.ArticleCollection.Clear(); 
      } 

      IsLoading = true; 
      ReadArticleList(); 

     } 

     public async void ReadArticleList() 
     { 
      try 
      { 
       if (CollectionHttpClient.IsDirty) 
       { 
        ArticleCollection = await CollectionHttpClient.GetAllArticlesAsync(); 
        IsLoading = false; 

       } 

      } 
      catch 
      {     
       MessageBox.Show("sorry, no data."); 
       IsLoading = false; 
      } 

     } 

     public event PropertyChangedEventHandler PropertyChanged; 
     private void NotifyPropertyChanged(String propertyName) 
     { 
      PropertyChangedEventHandler handler = PropertyChanged; 
      if (null != handler) 
      { 
       handler(this, new PropertyChangedEventArgs(propertyName)); 
      } 
     } 

    } 
} 

ответ

0

, наконец, я прошел через это. Я каждый раз обновляю ArticleCollection, это причина. Событие ItemRealized запускается каждый раз, когда элемент, назначенный контейнеру пользовательского интерфейса, каждый раз, пока новый элемент не назначается контейнеру пользовательского интерфейса.

В последний раз веб-api не возвращает результат, так как на последней странице нет результата. и на этот раз я не назначаю результат в ArticleCollection. Поэтому longlistselector ничего не показывает

Измените метод

public async void ReadArticleList() 
     { 
      try 
      { 
       if (CollectionHttpClient.IsDirty) 
       { 
        ArticleCollection = await CollectionHttpClient.GetAllArticlesAsync(); 
        IsLoading = false; 

       } 

      } 
      catch 
      {     
       MessageBox.Show("sorry, no data."); 
       IsLoading = false; 
      } 

     } 

в:

private async void ReadArticleList(int pageNumber) 
     { 
      try 
      { 

       List<Article> articleList = new List<Article>(); 
       articleList = await CollectionHttpClient.GetArticlesByPageAsync(pageNumber); 

       foreach (var item in articleList) 
       { 
        this.ArticleCollection.Add(item); 
       } 

       IsLoading = false; 


      } 
      catch 
      { 
       MessageBox.Show("sorry, no data."); 
       IsLoading = false; 
      } 

     } 
+0

У меня такая же проблема, но я не понимаю ваше решение @max, не могли бы вы его улучшить. Я попытался перезагрузить элементы один за другим, но не работал. – Yogurtu

0

Я подозреваю, что, потому что вы не поднимайте свойство измененное событие, когда ArticleCollection задавать. Вот почему LongListSelector не обновился. ObservableCollection уведомляет только пользовательский интерфейс, когда элемент добавлен или удален из коллекции. Но когда свойство ObservableCollection само присваивается новому объекту ObservableCollection, вам нужно вручную изменить событие изменения свойства. Попробуйте изменить его как следует, и посмотреть, если он работает сейчас:

private ObservableCollection<Article> _articleCollection; 
public ObservableCollection<Article> ArticleCollection 
{ 
    get 
    { 
     return _articleCollection; 
    } 
    set 
    { 
     _articleCollection = value; 
     NotifyPropertyChanged("ArticleCollection"); 
    } 
} 

Другой вариант не переназначить ArticleCollection, как вы в настоящее время делали в ReadListArticle методе:

ArticleCollection = await CollectionHttpClient.GetAllArticlesAsync(); 

вместо этого, очистить коллекцию и добавить каждый новый элемент в коллекцию.

+0

первый вариант не работает для меня. – max

+0

Пожалуйста, улучшите свое решение, как это работает, свойство ручной onchanged? Я вызываю его, но он не обновляет контент в LLS, это должно быть ObservableConnection или может быть любым IEnumerable? @ har07 – Yogurtu

 Смежные вопросы

  • Нет связанных вопросов^_^