I am developing a mobile application using Xamarin.Forms
, and for testing purposes I am trying to read a local json
file and displaying its contents into a CarouselView
. However, I am not able to do it: I am correctly parsing the file, but then it is not showed in the UI.
The xaml
code (with only the CarouselView
part) is as follows:
<!-- Carousel view with all the contents -->
<CarouselView Grid.Row="1"
Loop="False"
x:Name="visitChoicheCarousel"
ItemsSource="{Binding Rooms}">
<CarouselView.ItemTemplate>
<DataTemplate>
<StackLayout>
<Frame HasShadow="True"
BorderColor="DarkGray"
CornerRadius="5"
Margin="20"
HeightRequest="300"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand">
<StackLayout>
<Label Text="{Binding Contents.Name}"
FontAttributes="Bold"
FontSize="Large"
HorizontalOptions="Center"
VerticalOptions="Center"
AutomationProperties.IsInAccessibleTree="True"/>
</StackLayout>
</Frame>
</StackLayout>
</DataTemplate>
</CarouselView.ItemTemplate>
</CarouselView>
The c#
script that parses the file is as follows:
using System.Net.Http;
using System.Collections.ObjectModel;
using Xamarin.Essentials;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using PalazzoVecchioDemo.Models;
using Newtonsoft.Json;
using System.IO;
using System.Collections.Generic;
using System.Threading.Tasks;
using System;
using Newtonsoft.Json.Linq;
using System.Diagnostics;
using System.Reflection;
namespace PalazzoVecchioDemo.Views
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class VisitChoice : ContentPage
{
private const string _json = "rooms.json";
public Room Rooms { get; set; } = new Room();
public VisitChoice()
{
InitializeComponent();
BindingContext = this;
}
protected override void OnAppearing()
{
base.OnAppearing();
var assembly = typeof(VisitChoice).GetTypeInfo().Assembly;
Stream stream = assembly.GetManifestResourceStream($"{assembly.GetName().Name}.{_json}");
using (var reader = new StreamReader(stream))
{
var jsonString = reader.ReadToEnd();
Rooms = JsonConvert.DeserializeObject<Room>(jsonString);
}
}
}
}
The class that contains the de-serialized file is as follows:
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Text;
namespace PalazzoVecchioDemo.Models
{
public class Rootobject
{
public Room[] Rooms { get; set; }
}
public class Room
{
[JsonProperty("ID")]
public string ID { get; set; }
public Content[] Contents { get; set; }
}
public class Content
{
[JsonProperty("Name")]
public string Name { get; set; }
[JsonProperty("ImageURI")]
public string ImageURI { get; set; }
}
}
Could anyone help me?
CodePudding user response:
first, your ItemsSource
needs to be an IEnumerable
this is wrong, Room
is a single Room
object
ItemsSource="{Binding Rooms}"
you probably want to do this, because Contents
is an array
ItemsSource="{Binding Rooms.Contents}"
then also change this
Text="{Binding Contents.Name}"
to this
Text="{Binding Name}"
finally, either assign the BindingContext
after you load the data, or use INotifyPropertyChanged
to signal that Rooms
has been updated
CodePudding user response:
public partial class VisitChoice : ContentPage, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
private const string FileName = "Room.json";
private List<Room> _rooms;
public List<Room> Rooms
{
get => _rooms;
set
{
_rooms = value;
NotifyPropertyChanged();
}
}
public VisitChoice()
{
InitializeComponent();
BindingContext = this;
}
protected override void OnAppearing()
{
base.OnAppearing();
var assembly = IntrospectionExtensions.GetTypeInfo(typeof(VisitChoice)).Assembly;
var stream = assembly.GetManifestResourceStream($"{assembly.GetName().Name}.{FileName}");
using (var reader = new StreamReader(stream))
{
var jsonString = reader.ReadToEnd();
Rooms = JsonConvert.DeserializeObject<List<Room>>(jsonString);
}
}
}