解析本地 json 文件并将其显示在 Xamarin Forms 的 CarouselView 中
Parsing local json file and displaying it in a CarouselView in Xamarin Forms
我正在使用 Xamarin.Forms
开发移动应用程序,出于测试目的,我正在尝试读取本地 json
文件并将其内容显示到 CarouselView
中。但是,我做不到:我正确地解析了文件,但是它没有显示在 UI.
中
xaml
代码(只有CarouselView
部分)如下:
<!-- 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>
解析文件的c#
脚本如下:
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);
}
}
}
}
包含反序列化文件的class如下:
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; }
}
}
谁能帮帮我?
首先,您的 ItemsSource
需要 IEnumerable
这是错误的,Room
是一个单一的Room
对象
ItemsSource="{Binding Rooms}"
你可能想这样做,因为Contents
是一个数组
ItemsSource="{Binding Rooms.Contents}"
然后也改变这个
Text="{Binding Contents.Name}"
至此
Text="{Binding Name}"
最后,要么在加载数据后分配BindingContext
,要么使用INotifyPropertyChanged
表示Rooms
已更新
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);
}
}
}
您可以参考下面的代码。
Xaml:
<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 name}"
FontAttributes="Bold"
FontSize="Large"
HorizontalOptions="Center"
VerticalOptions="Center"
AutomationProperties.IsInAccessibleTree="True"/>
</StackLayout>
</Frame>
</StackLayout>
</DataTemplate>
</CarouselView.ItemTemplate>
</CarouselView>
代码:
public partial class Page20 : ContentPage
{
public ObservableCollection<Contact> Rooms { get; set; }
public Page20()
{
InitializeComponent();
string _json = "rooms.json";
Room ObjContactList = new Room();
var assembly = typeof(Page20).GetTypeInfo().Assembly;
Stream stream = assembly.GetManifestResourceStream($"{assembly.GetName().Name}.{_json}");
using (var reader = new StreamReader(stream))
{
var jsonString = reader.ReadToEnd();
//Converting JSON Array Objects into generic list
ObjContactList = JsonConvert.DeserializeObject<Room>(jsonString);
}
Rooms = new ObservableCollection<Contact>();
foreach (var item in ObjContactList.contacts.ToList())
{
Rooms.Add(item);
}
this.BindingContext = this;
}
}
public class Room
{
public Contact[] contacts { get; set; }
}
public class Contact
{
public string name { get; set; }
public string email { get; set; }
public string phoneNumber { get; set; }
}
Json数据:
{
"contacts": [
{
"name": "JOE",
"email": "name@handle",
"phoneNumber": "123-456-7890"
},
{
"name": "JYM",
"email": "name@handle",
"phoneNumber": "123-456-7890"
},
{
"name": "JYM",
"email": "name@handle",
"phoneNumber": "123-456-7890"
}
]
}
我正在使用 Xamarin.Forms
开发移动应用程序,出于测试目的,我正在尝试读取本地 json
文件并将其内容显示到 CarouselView
中。但是,我做不到:我正确地解析了文件,但是它没有显示在 UI.
xaml
代码(只有CarouselView
部分)如下:
<!-- 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>
解析文件的c#
脚本如下:
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);
}
}
}
}
包含反序列化文件的class如下:
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; }
}
}
谁能帮帮我?
首先,您的 ItemsSource
需要 IEnumerable
这是错误的,Room
是一个单一的Room
对象
ItemsSource="{Binding Rooms}"
你可能想这样做,因为Contents
是一个数组
ItemsSource="{Binding Rooms.Contents}"
然后也改变这个
Text="{Binding Contents.Name}"
至此
Text="{Binding Name}"
最后,要么在加载数据后分配BindingContext
,要么使用INotifyPropertyChanged
表示Rooms
已更新
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);
}
}
}
您可以参考下面的代码。
Xaml:
<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 name}"
FontAttributes="Bold"
FontSize="Large"
HorizontalOptions="Center"
VerticalOptions="Center"
AutomationProperties.IsInAccessibleTree="True"/>
</StackLayout>
</Frame>
</StackLayout>
</DataTemplate>
</CarouselView.ItemTemplate>
</CarouselView>
代码:
public partial class Page20 : ContentPage
{
public ObservableCollection<Contact> Rooms { get; set; }
public Page20()
{
InitializeComponent();
string _json = "rooms.json";
Room ObjContactList = new Room();
var assembly = typeof(Page20).GetTypeInfo().Assembly;
Stream stream = assembly.GetManifestResourceStream($"{assembly.GetName().Name}.{_json}");
using (var reader = new StreamReader(stream))
{
var jsonString = reader.ReadToEnd();
//Converting JSON Array Objects into generic list
ObjContactList = JsonConvert.DeserializeObject<Room>(jsonString);
}
Rooms = new ObservableCollection<Contact>();
foreach (var item in ObjContactList.contacts.ToList())
{
Rooms.Add(item);
}
this.BindingContext = this;
}
}
public class Room
{
public Contact[] contacts { get; set; }
}
public class Contact
{
public string name { get; set; }
public string email { get; set; }
public string phoneNumber { get; set; }
}
Json数据:
{
"contacts": [
{
"name": "JOE",
"email": "name@handle",
"phoneNumber": "123-456-7890"
},
{
"name": "JYM",
"email": "name@handle",
"phoneNumber": "123-456-7890"
},
{
"name": "JYM",
"email": "name@handle",
"phoneNumber": "123-456-7890"
}
]
}