2017-11-04 5 views
0

UWP、Visual Studio、およびMVVMを初めて使用しています。今、私は比較的簡単なアプリケーションを持っています。そこでは、学生とそのコースを表示するだけです。私は、外部のデータベースにすべてのデータを格納しているし、情報を逆シリアル化するためにNewtonSoft JSONでWeb APIを使用しています。JSON to ObservableCollectionをListViewで使用する

私は2つのクラス「学生」と「コース」を持っています。各生徒にはコースを含むListプロパティがあります。

各Student's Courses-ListをAPIから取得して正しく表示するにはどうすればよいですか?

学生クラス(モデル):

public class Students { 
    public int Id { get; set; } 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public virtual List<Courses> Courses {get; set;} 
} 

コースクラス(モデル):

public class Courses { 
    public int Id { get; set; } 
    public string CourseName { get; set; } 
    public string CourseCode { get; set; } 
    public virtual List<Students> Students { get; set; } 
} 

XAML(ビュー):

<Page.DataContext> 
    <vm:NewStudentViewModel x:Name="viewModel" /> 
</Page.DataContext> 

<RelativePanel> 
    <ListView 
     RelativePanel.AlignLeftWithPanel="True" 
     RelativePanel.AlignRightWithPanel="True" 
     ItemsSource="{Binding StudentList}" 
     Name="StudentList"> 
     <ListView.ItemTemplate> 
      <DataTemplate> 
       <StackPanel Orientation="Horizontal"> 
        <TextBlock Text="{Binding FirstName, Mode=OneWay}" Margin="5 0 0 0" /> 
        <TextBlock Text="{Binding LastName, Mode=OneWay}" Margin="5 0 0 0"/> 
        <TextBlock Text="{Binding CourseName, Mode=OneWay}" Margin="5 0 0 0"/> 
       </StackPanel> 
      </DataTemplate> 
     </ListView.ItemTemplate> 
    </ListView> 
</RelativePanel> 

私のViewModel:

public class NewStudentViewModel : ViewModelBase, INotifyPropertyChanged { 

    public NewStudentViewModel() { 
     InitaializeDataAsync(); 
    } 

    ObservableCollection<Students> students; 
    public ObservableCollection<Students> StudentList { 
     get { 
      return students; 
     } 
     set { 
      Set(ref students, value); 
      RaisePropertyChanged(nameof(StudentList)); 
     } 
    } 

    public async Task<ObservableCollection<Students>> GetStudendts() { 
     if (StudentList == null) { 
      HttpClient Client = new HttpClient(); 
      HttpResponseMessage responseMessage = await Client.GetAsync("http://localhost:50491/api/students"); 

      if (responseMessage.IsSuccessStatusCode) { 
       var Jsonresponse = await Client.GetStringAsync("http://localhost:50491/api/students"); 
       var StudentModel = JsonConvert.DeserializeObject<ObservableCollection<Students>>(Jsonresponse); 
       return StudentModel; 
      } 
     } 
     return StudentList; 
    } 

    private async Task InitaializeDataAsync() { 
     StudentList = await GetStudendts(); 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
    protected void RaisePropertyChanged(string propertyName) { 
     PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 
    } 

    private string _FirstName; 
    public string FirstName { 
     get { 
      return _FirstName; 
     } 
     set { 

      _FirstName = value; 
      RaisePropertyChanged(nameof(FirstName)); 
     } 
    } 

    private string _LastName; 
    public string LastName { 
     get { 
      return _LastName; 
     } 
     set { 
      _LastName = value; 
      RaisePropertyChanged(nameof(LastName)); 
     } 
    } 

    private string _CourseName; 
    public string CourseName { 
     get { 
      return _CourseName; 
     } 
     set { 
      _CourseName = value; 
      RaisePropertyChanged(nameof(CourseName)); 
     } 
    } 
} 

は、今のところ私はFirstNameおよび学生の姓を表示することができるよ、私は、各学生のためのコース・リストを表示する方法を見つけ出すことはできません。

PS(ボーナス質問)(それはちょうどコースの名前を表示するには十分です):マイ/ API /学生は、このXMLを返します。

<ArrayOfStudents xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/Model"> 
    <Students> 
     <Courses i:nil="true"/> 
     <FirstName>Olaf</FirstName> 
     <Id>1</Id> 
     <LastName>Roglebang</LastName> 
    </Students> 
    <Students> 
     <Courses i:nil="true"/> 
     <FirstName>Winther</FirstName> 
     <Id>2</Id> 
     <LastName>Summers</LastName> 
    </Students> 
    <Students> 
     <Courses i:nil="true"/> 
     <FirstName>James</FirstName> 
     <Id>3</Id> 
     <LastName>Bond</LastName> 
    </Students> 
</ArrayOfStudents> 

なぜそれが正しくコースを表示しませんか?

編集1: これはJSON形式でAPI /学生から私の結果である:

[ 
    { 
     "Id": 1, 
     "FirstName": "sample string 2", 
     "LastName": "sample string 3", 
     "Courses": [ 
      { 
       "Id": 1, 
       "CourseName": "sample string 2", 
       "CourseCode": "sample string 3", 
       "Students": [] 
      }, 
      { 
       "Id": 1, 
       "CourseName": "sample string 2", 
       "CourseCode": "sample string 3", 
       "Students": [] 
      } 
     ] 
    }, 
    { 
     "Id": 1, 
     "FirstName": "sample string 2", 
     "LastName": "sample string 3", 
     "Courses": [ 
      { 
       "Id": 1, 
       "CourseName": "sample string 2", 
       "CourseCode": "sample string 3", 
       "Students": [] 
      }, 
      { 
       "Id": 1, 
       "CourseName": "sample string 2", 
       "CourseCode": "sample string 3", 
       "Students": [] 
      } 
     ] 
    } 
] 
+2

問題はあなたのAPIコードです。コースを返すわけではありません。まず、APIのURLをブラウザに入力し、必要なデータがすべて返されていることを確認します。一度それを確認したら、次の部分に移動します。それぞれの部品を別々に作業する。それが動作したら、 'InitaializeDataAsync'メソッドでダミーデータを作成し、アプリがダミーデータを表示できるかどうかを確認します。それが機能すると、ダミーデータをコメントアウトしてAPIを呼び出します。あなたの仕事をより小さなユニットに分割し、それぞれのユニットで作業し、次のユニットと一体化し続けるなど。 – CodingYoshi

+0

APIのエラーが修正されました。私は今データを取得することができますが、私はそれをビューにバインドするとき、 "Winther Summers System.Collections.Generic.List'1 [Model.Courses]"の代わりに "Winther Summers Calculus 370 " – Fred

+1

これを' await Client.GetStringAsync( "http:// localhost:50491/api/students") 'と呼ぶときに、サンプルのjason値をここに入力してください。 –

答えて

1

あなたのJSONのサンプル値をチェックした後、私は、あなたがこの行var StudentModel = JsonConvert.DeserializeObject<ObservableCollection<Students>>(Jsonresponse);を使用する場合は、JSON値を解析することがわかりましたStudentsコレクションを取得すると、Studentsオブジェクトには、Couresesコレクションが含まれています。だから、あなたのxamlは次のように変更する必要があります:

<ListView 
    RelativePanel.AlignLeftWithPanel="True" 
    RelativePanel.AlignRightWithPanel="True" 
    ItemsSource="{Binding StudentList}"> 
     <ListView.ItemTemplate> 
      <DataTemplate> 
       <StackPanel Orientation="Horizontal"> 
        <TextBlock Text="{Binding FirstName, Mode=OneWay}" Margin="5 0 0 0" /> 
        <TextBlock Text="{Binding LastName, Mode=OneWay}" Margin="5 0 0 0"/> 
        <ListView ItemsSource="{Binding Courses}"> 
         <ListView.ItemTemplate> 
          <DataTemplate> 
           <StackPanel> 
            <TextBlock Text="{Binding CourseName, Mode=OneWay}" Margin="5 0 0 0"/> 
           </StackPanel> 
          </DataTemplate> 
         </ListView.ItemTemplate> 
        </ListView> 
       </StackPanel> 
      </DataTemplate> 
     </ListView.ItemTemplate> 
</ListView> 
関連する問題