解析本地 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"
   }
  ]
}