【问题标题】:How to get the information from JSON array into list and into XAML如何从 JSON 数组获取信息到列表和 XAML
【发布时间】:2019-11-08 10:07:07
【问题描述】:

我正在使用 Xamarin 做一个跨平台项目。现在我遇到了 API JSON 数据、数据类和 ListView 的问题。

这是我的 TideInfo 类中的代码:

public class TideRoot {
    [JsonProperty("EventType")]
    public string EventType { get; set; } = string.Empty;

    [JsonProperty("DateTime")]
    public DateTime DateTime { get; set; }

    [JsonProperty("IsApproximateTime")]
    public bool IsApproximateTime { get; set; }

    [JsonProperty("Height")]
    public double Height { get; set; }

    [JsonProperty("IsApproximateHeight")]
    public bool IsApproximateHeight { get; set; }

    [JsonProperty("Filtered")]
    public bool Filtered { get; set; }

    [JsonIgnore]
    public string DisplayTide => $"Height: {EventType ?? string.Empty}, {Height}";


}

public class TideRootList {
    public List<TideRoot> ListItem { get; set; } }

我使用 json2csharp 来获取 TideRoot 列表,添加了 DisplayTide 以便我可以在列表中同时显示 EventType 和 Height。最近,我添加了 TideRootList 以获取 7 天的潮汐信息列表。

这是 JSON 文件:

[{
  "EventType": "LowWater",
  "DateTime": "2019-11-08T01:32:00",
  "IsApproximateTime": false,
  "Height": 1.8388111705145762,
  "IsApproximateHeight": false,
  "Filtered": false
}, {
  "EventType": "HighWater",
  "DateTime": "2019-11-08T08:56:00",
  "IsApproximateTime": false,
  "Height": 4.2101062451792144,
  "IsApproximateHeight": false,
  "Filtered": false
}, {
  "EventType": "LowWater",
  "DateTime": "2019-11-08T14:03:00",
  "IsApproximateTime": false,
  "Height": 1.7989273407141986,
  "IsApproximateHeight": false,
  "Filtered": false
}, {
  "EventType": "HighWater",
  "DateTime": "2019-11-08T21:04:00",
  "IsApproximateTime": false,
  "Height": 4.070738079705702,
  "IsApproximateHeight": false,
  "Filtered": false
}, {
  "EventType": "LowWater",
  "DateTime": "2019-11-09T02:16:00",
  "IsApproximateTime": false,
  "Height": 1.6184884034712226,
  "IsApproximateHeight": false,
  "Filtered": false
}, {
  "EventType": "HighWater",
  "DateTime": "2019-11-09T09:34:00",
  "IsApproximateTime": false,
  "Height": 4.4085443850273309,
  "IsApproximateHeight": false,
  "Filtered": false
}, {
  "EventType": "LowWater",
  "DateTime": "2019-11-09T14:44:00",
  "IsApproximateTime": false,
  "Height": 1.5501832117158008,
  "IsApproximateHeight": false,
  "Filtered": false
}, {
  "EventType": "HighWater",
  "DateTime": "2019-11-09T21:44:00",
  "IsApproximateTime": false,
  "Height": 4.2701942634884968,
  "IsApproximateHeight": false,
  "Filtered": false
}, {
  "EventType": "LowWater",
  "DateTime": "2019-11-10T02:56:00",
  "IsApproximateTime": false,
  "Height": 1.4077035385806112,
  "IsApproximateHeight": false,
  "Filtered": false
}, {
  "EventType": "HighWater",
  "DateTime": "2019-11-10T10:09:00",
  "IsApproximateTime": false,
  "Height": 4.5597566246677248,
  "IsApproximateHeight": false,
  "Filtered": false
}, {
  "EventType": "LowWater",
  "DateTime": "2019-11-10T15:20:00",
  "IsApproximateTime": false,
  "Height": 1.33459759647378,
  "IsApproximateHeight": false,
  "Filtered": false
}, {
  "EventType": "HighWater",
  "DateTime": "2019-11-10T22:21:00",
  "IsApproximateTime": false,
  "Height": 4.4226776330873276,
  "IsApproximateHeight": false,
  "Filtered": false
}, {
  "EventType": "LowWater",
  "DateTime": "2019-11-11T03:32:00",
  "IsApproximateTime": false,
  "Height": 1.2396397924330329,
  "IsApproximateHeight": false,
  "Filtered": false
}, {
  "EventType": "HighWater",
  "DateTime": "2019-11-11T10:44:00",
  "IsApproximateTime": false,
  "Height": 4.6557658698506978,
  "IsApproximateHeight": false,
  "Filtered": false
}, {
  "EventType": "LowWater",
  "DateTime": "2019-11-11T15:55:00",
  "IsApproximateTime": false,
  "Height": 1.1711223007079854,
  "IsApproximateHeight": false,
  "Filtered": false
}, {
  "EventType": "HighWater",
  "DateTime": "2019-11-11T22:57:00",
  "IsApproximateTime": false,
  "Height": 4.5263662430387752,
  "IsApproximateHeight": false,
  "Filtered": false
}, {
  "EventType": "LowWater",
  "DateTime": "2019-11-12T04:08:00",
  "IsApproximateTime": false,
  "Height": 1.1263357912996472,
  "IsApproximateHeight": false,
  "Filtered": false
}, {
  "EventType": "HighWater",
  "DateTime": "2019-11-12T11:17:00",
  "IsApproximateTime": false,
  "Height": 4.7038380223666625,
  "IsApproximateHeight": false,
  "Filtered": false
}, {
  "EventType": "LowWater",
  "DateTime": "2019-11-12T16:29:00",
  "IsApproximateTime": false,
  "Height": 1.0599435514996523,
  "IsApproximateHeight": false,
  "Filtered": false
}, {
  "EventType": "HighWater",
  "DateTime": "2019-11-12T23:29:00",
  "IsApproximateTime": false,
  "Height": 4.5937485679887731,
  "IsApproximateHeight": false,
  "Filtered": false
}, {
  "EventType": "LowWater",
  "DateTime": "2019-11-13T04:42:00",
  "IsApproximateTime": false,
  "Height": 1.0650050994934075,
  "IsApproximateHeight": false,
  "Filtered": false
}, {
  "EventType": "HighWater",
  "DateTime": "2019-11-13T11:48:00",
  "IsApproximateTime": false,
  "Height": 4.7189203663268842,
  "IsApproximateHeight": false,
  "Filtered": false
}, {
  "EventType": "LowWater",
  "DateTime": "2019-11-13T17:02:00",
  "IsApproximateTime": false,
  "Height": 0.99227216956188025,
  "IsApproximateHeight": false,
  "Filtered": false
}, {
  "EventType": "HighWater",
  "DateTime": "2019-11-14T00:00:00",
  "IsApproximateTime": false,
  "Height": 4.6379169444371362,
  "IsApproximateHeight": false,
  "Filtered": false
}, {
  "EventType": "LowWater",
  "DateTime": "2019-11-14T05:17:00",
  "IsApproximateTime": false,
  "Height": 1.0460921771289937,
  "IsApproximateHeight": false,
  "Filtered": false
}, {
  "EventType": "HighWater",
  "DateTime": "2019-11-14T12:17:00",
  "IsApproximateTime": false,
  "Height": 4.7116384452230751,
  "IsApproximateHeight": false,
  "Filtered": false
}, {
  "EventType": "LowWater",
  "DateTime": "2019-11-14T17:36:00",
  "IsApproximateTime": false,
  "Height": 0.9624477944154356,
  "IsApproximateHeight": false,
  "Filtered": false
}]

这就是我处理 API 的方式:

public async Task<TideRootList> GetTideInfo(string id, string duration)
        {
            using (var client = new HttpClient())
            {
                // Request headers
                client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", "223604c97163487bb857cfb554c96c90");

                var url = string.Format(TideInfo, id, duration);
                var json = await client.GetStringAsync(url);

                if (string.IsNullOrWhiteSpace(json))
                    return null;

                json.Replace("[", "").Replace("]", "");

                //deserialize the array into a list of Result objects, and take the object at index zero.
                var result = JsonConvert.DeserializeObject<List<TideRootList>>(json);
                return result[0];
            }

        }

最后一部分是执行 API 方法并将信息提供给 XAML 的 viewModel。两者都在这里:

TideRootList tidelist;
        public TideRootList TideList
        {
            get { return tidelist; }
            set { tidelist = value; OnPropertyChanged(); }
        }


 TideList = await WeatherService.GetTideInfo("0065", "7");

还有 XAML:

<StackLayout Padding="10" Spacing="10">
            <ListView ItemsSource="{Binding TideRootList.ListItem}"
              HasUnevenRows="True"
              CachingStrategy="RecycleElement"
              IsPullToRefreshEnabled="True"
              RefreshCommand="{Binding GetWeatherCommand}"
              IsRefreshing="{Binding IsBusy, Mode=OneWay}"
              RowHeight="66"
              x:Name="ListViewTide">
                <ListView.SeparatorColor>
                    <OnPlatform x:TypeArguments="Color" iOS="Transparent"/>
                </ListView.SeparatorColor>
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <ViewCell>
                            <StackLayout Orientation="Horizontal" Padding="10,0,0,0">
                                <StackLayout Padding="10" Spacing="5">
                                    <Label Text="{Binding DisplayTide}"
                                   TextColor="#3498db"
                                           FontAttributes="Bold"
                                   Style="{DynamicResource ListItemTextStyle}"/>
                                    <Label Text="{Binding DisplayTide}" 
                                   Style="{DynamicResource ListItemDetailTextStyle}"/>
                                </StackLayout>
                            </StackLayout>
                        </ViewCell>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
        </StackLayout>

经过多次不同的测试,我无法在应用程序上显示 DisplayTide,它只是一个空白区域。请告诉我我错过了什么。谢谢。

【问题讨论】:

  • TideList = await WeatherService.GetTideInfo("0065", "7");这行你调试了吗?是否为空?
  • 是的,我有。现在一切都很好。

标签: c# json api xaml xamarin


【解决方案1】:

你在ListView.ItemsSource的绑定路径上弄错了。

应该是TideList.ListItem

额外建议

使用 json 反序列化时不需要去掉括号,可以直接获取列表。

public async Task<List<TideRoot>> GetTideInfo(string id, string duration)
    {
        using (var client = new HttpClient())
        {
            // Request headers
            client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", "223604c97163487bb857cfb554c96c90");

            var url = string.Format(TideInfo, id, duration);
            var json = await client.GetStringAsync(url);

            if (string.IsNullOrWhiteSpace(json))
                return null;

            //deserialize the array into a list of Result objects, and take the object at index zero.
            var result = JsonConvert.DeserializeObject<List<TideRoot>>(json);
            return result;
        }

    }
       
  //in model
  List<TideRoot> tidelist;
  public List<TideRoot> TideList
  {
      get { return tidelist; }
      set { tidelist = value; OnPropertyChanged(); }
  }
  TideList = await WeatherService.GetTideInfo("0065", "7");


  //xaml
  <ListView ItemsSource="{Binding TideList}"

【讨论】:

  • 非常感谢,Cole,这是一个如此简单的更改,但我已经绕了好几个小时了。这解决了问题。
猜你喜欢
  • 2014-02-11
  • 2021-10-20
  • 1970-01-01
  • 2021-05-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多