2016-08-09 106 views
0

Ich versuche, ein Raster aus einer JSON-URL mit JSON.NET zu füllen. Ich konnte die Daten aus der URL deserialisieren und an die Modellklasse binden. Es ist jedoch nicht an die XAML-Seite gebunden. Hier ist meine Modellklasse und MovieManger Klasse:UWP Databinding von JSON funktioniert nicht

using Newtonsoft.Json; 
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Net.Http; 
using System.Text; 
using System.Threading.Tasks; 

namespace DataBindingTest3.Models 
{ 
    public class AmgMovie 
    { 
     public string state { get; set; } 
     public Data data { get; set; } 
    } 
    public class Data 
    { 
     public int type { get; set; } 
     public string type_name { get; set; } 
     public Movie[] movies { get; set; } 
    } 

    public class Movie 
    { 
     public string id { get; set; } 
     public string title { get; set; } 
     public string movie_desc { get; set; } 
     public string movie_actors { get; set; } 
     public string movie_director { get; set; } 
     public string music_director { get; set; } 
     public string movie_year { get; set; } 
     public string movie_month { get; set; } 
     public string realeased_date { get; set; } 
     public string image { get; set; } 
     public string portrait_image { get; set; } 
     public string movie_list_image_url { get; set; } 
     public string movie_poster_url { get; set; } 
     public string duration { get; set; } 
     public string url { get; set; } 
     public string download_url { get; set; } 
     public string trailer_url { get; set; } 
     public int allow_download { get; set; } 
    } 

    public class MovieManager 
    { 
     public static async Task<List<Movie>> GetMovies() 
     { 
      var movies = new List<Movie>(); 
      var amg = new HttpClient(); 
      HttpResponseMessage response = await amg.GetAsync(new Uri("some URL")); 
      var json = await response.Content.ReadAsStringAsync(); 
      AmgMovie Movie = JsonConvert.DeserializeObject<AmgMovie>(json); 

      for (uint i = 0; i < Movie.data.movies.Count(); i++) 
      { 
       string id1 = Movie.data.movies[i].id; 
       string title1 = Movie.data.movies[i].title; 
       string portrait_image1 = Movie.data.movies[i].portrait_image; 

       movies.Add(new Movie { id = id1, title = title1, portrait_image = portrait_image1 }); 
      } 

      return movies; 

     } 
    } 
} 

Dies ist der Code hinter der XAML Seite lautet:

public sealed partial class MainPage : Page 
    { 
     private List<Movie> Movie; 
     public MainPage() 
     { 
      this.InitializeComponent(); 
     } 

     private async void Page_Loaded(object sender, RoutedEventArgs e) 
     { 
      Movie = await MovieManager.GetMovies(); 
     } 
    } 

Dies ist die XAML Seite Markup:

<Page 
    x:Class="DataBindingTest3.MainPage" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="using:DataBindingTest3" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:data="using:DataBindingTest3.Models" 
    Loaded="Page_Loaded" 
    mc:Ignorable="d"> 

    <Page.Resources> 
     <DataTemplate x:DataType="data:Movie" x:Key="MovieDataTemplate"> 
      <StackPanel> 
       <TextBlock x:Name="movieID" Text="{x:Bind id}" FontSize="12" Foreground="Black" /> 
       <Image x:Name="moviePoster" Source="{x:Bind portrait_image}" Width="145" Height="214"/> 
       <TextBlock x:Name="movieName" Text="{x:Bind title}" FontSize="16" Foreground="Black"/> 
      </StackPanel> 
     </DataTemplate> 
    </Page.Resources> 
    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="*" /> 
      <RowDefinition Height="100" /> 
     </Grid.RowDefinitions> 

     <GridView Grid.Row="0" ItemsSource="{x:Bind Movie}" ItemTemplate="{StaticResource MovieDataTemplate}"> 

     </GridView> 

    </Grid> 
</Page> 

ich auch versucht, ohne json binden und nur einige Beispieldaten in der MovieManager-Klasse eingeben und es perfekt bindet. Mir ist aufgefallen, dass beim Debuggen sowohl der Sample-Methode als auch der Json-Methode beide Methoden Daten zurückgeben, allerdings nur, wenn ich die Beispieldaten des Debuggers in die XAML Page.g.cs eingebunden habe, um die Daten zu binden.

Antwort

0

Sie haben zwei Möglichkeiten:

  1. In den MainPage.xaml.cs der Film Feld des Typs beobachtbaren Sammlung zu ändern, und kopieren Ergebnis der Sammlung wie dies die Elemente der GetMovies() funcion ist: (UI ändern, wenn der Inhalt der Filme Sammlung verändert (hinzufügen/entfernen Elemente))

    private ObservableCollection<Movie> Movies = new ObservableCollection<Movie>(); 
    
    private async void AboutPage_Loaded(object sender, RoutedEventArgs e) 
    { 
        foreach (var movie in await GetMovies()) 
        { 
         Movie.Add(movie); 
        } 
    } 
    
  2. Sie machen eine Eigenschaft für die Filme Liste mit der INotifyPropertyChanged Umsetzung, und ändern Sie die x: Bind-Modus OneWay: (UI ändern, wenn Die Eigenschaft "Filme" wird geändert d (und nicht deren Inhalt))

    public sealed partial class MainPage : Page, INotifyPropertyChanged 
    { 
        public event PropertyChangedEventHandler PropertyChanged; 
    
        private List<Movie> _movies; 
        public List<Movie> Movies 
        { 
         get { return _movies; } 
         set { if(value != _movies) { _movies = value; PropertyChanged?.Invoke(nameof(Movies)); } } 
        } 
    
        public MainPage() 
        { 
         this.InitializeComponent(); 
        } 
    
        private async void Page_Loaded(object sender, RoutedEventArgs e) 
        { 
         Movies = await MovieManager.GetMovies(); 
        } 
    } 
    

    XAML:

    <GridView Grid.Row="0" ItemsSource="{x:Bind Movies, Mode=OneWay}" ItemTemplate="{StaticResource MovieDataTemplate}" /> 
    

In der ersten Version, die Benutzeroberfläche wird sich nicht ändern, wenn Sie die Filme mit einer neuen Liste überschrieben. In der zweiten Version ändert sich die Benutzeroberfläche nicht, wenn Sie Elemente zur Liste hinzufügen/entfernen.

Sie können diese beiden Versionen kombinieren.

+0

Danke, es hat funktioniert. – John

0

Sie müssen die Movie-Sammlung ObservableCollection und nicht nur List haben.

+0

Hallo, ich habe versucht, es zu ObservableCollection zu ändern. Kein Kompilierungsfehler. Funktioniert auch nicht. – John