Windows Phone 8.1 开发:如何从列表视图的反序列化 Json 根对象绑定数据
Windows Phone 8.1 Development: How to Bind Data from the Deserialized Json Root Object for the List View
我正在学习 WP 8.1 应用程序开发,现在正在做一个简单的天气应用程序:我正在读取来自 http://openweathermap.org/ 的天气 Json 数据,Json 数据本身已成功检索,但我无法将数据绑定到我的列表视图。详情如下:
{
"cod": "200",
"message": 0.0907,
"city": {
"id": 658225,
"name": "Helsinki",
"coord": {
"lon": 24.93545,
"lat": 60.169521
},
"country": "FI",
"population": 558457
},
"cnt": 7,
"list": [
{
"dt": 1426413600,
"temp": {
"day": 272.64,
"min": 270.84,
"max": 272.64,
"night": 270.84,
"eve": 272.64,
"morn": 272.64
},
"pressure": 1062.73,
"humidity": 89,
"weather": [
{
"id": 800,
"main": "Clear",
"description": "sky is clear",
"icon": "01d"
}
],
"speed": 5.01,
"deg": 70,
"clouds": 0
},
{
"dt": 1426500000,
"temp": {
"day": 274.26,
"min": 271.16,
"max": 274.26,
"night": 272.43,
"eve": 273.39,
"morn": 271.16
},
"pressure": 1065.67,
"humidity": 90,
"weather": [
{
"id": 800,
"main": "Clear",
"description": "sky is clear",
"icon": "01d"
}
],
"speed": 2.76,
"deg": 78,
"clouds": 0
},
{
"dt": 1426586400,
"temp": {
"day": 274.51,
"min": 272.16,
"max": 274.7,
"night": 272.99,
"eve": 273.9,
"morn": 272.16
},
"pressure": 1062,
"humidity": 92,
"weather": [
{
"id": 800,
"main": "Clear",
"description": "sky is clear",
"icon": "01d"
}
],
"speed": 3.66,
"deg": 170,
"clouds": 0
},
{
"dt": 1426672800,
"temp": {
"day": 274.69,
"min": 272.04,
"max": 275.19,
"night": 272.18,
"eve": 274.77,
"morn": 272.04
},
"pressure": 1056.08,
"humidity": 94,
"weather": [
{
"id": 800,
"main": "Clear",
"description": "sky is clear",
"icon": "01d"
}
],
"speed": 2.02,
"deg": 225,
"clouds": 0
},
{
"dt": 1426759200,
"temp": {
"day": 277.33,
"min": 275.68,
"max": 277.33,
"night": 275.68,
"eve": 276.02,
"morn": 275.87
},
"pressure": 1016.04,
"humidity": 0,
"weather": [
{
"id": 500,
"main": "Rain",
"description": "light rain",
"icon": "10d"
}
],
"speed": 4.95,
"deg": 256,
"clouds": 81,
"rain": 0.47
},
{
"dt": 1426845600,
"temp": {
"day": 275.47,
"min": 271.06,
"max": 275.47,
"night": 271.06,
"eve": 273.94,
"morn": 275.27
},
"pressure": 1027.17,
"humidity": 0,
"weather": [
{
"id": 600,
"main": "Snow",
"description": "light snow",
"icon": "13d"
}
],
"speed": 4.8,
"deg": 30,
"clouds": 92,
"snow": 0.04
},
{
"dt": 1426932000,
"temp": {
"day": 274.33,
"min": 270.47,
"max": 274.33,
"night": 270.47,
"eve": 272.02,
"morn": 270.9
},
"pressure": 1035.35,
"humidity": 0,
"weather": [
{
"id": 800,
"main": "Clear",
"description": "sky is clear",
"icon": "01d"
}
],
"speed": 2.81,
"deg": 84,
"clouds": 3
}
]
}
然后生成天气数据class并参考http://json2csharp.com/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WeatherApp.Models
{
public class WeatherData
{
public class RootObject
{
public string cod { get; set; }
public double message { get; set; }
public City city { get; set; }
public int cnt { get; set; }
public List<Day> list { get; set; }
}
public class Coord
{
public double lon { get; set; }
public double lat { get; set; }
}
public class City
{
public int id { get; set; }
public string name { get; set; }
public Coord coord { get; set; }
public string country { get; set; }
public int population { get; set; }
}
public class Temp
{
public double day { get; set; }
public double min { get; set; }
public double max { get; set; }
public double night { get; set; }
public double eve { get; set; }
public double morn { get; set; }
}
public class Weather
{
public int id { get; set; }
public string main { get; set; }
public string description { get; set; }
public string icon { get; set; }
}
public class Day
{
//public int dt { get; set; }
private int _dt;
public int dt
{
get { return _dt; }
set
{
_dt = value;
var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
time = epoch.AddSeconds(value);
}
}
private DateTime _time;
public DateTime time
{
get { return _time; }
set { _time = value; }
}
public Temp temp { get; set; }
public double pressure { get; set; }
public int humidity { get; set; }
public List<Weather> weather { get; set; }
public double speed { get; set; }
public int deg { get; set; }
public int clouds { get; set; }
public double? rain { get; set; }
public double? snow { get; set; }
}
}
}
来自 WeatherInforPage.xaml.cs:
protected override void OnNavigatedTo(NavigationEventArgs e)
{
this.navigationHelper.OnNavigatedTo(e);
String receiveText = e.Parameter.ToString();
System.Diagnostics.Debug.WriteLine("WeatherInfoPage received handed over weather information: " + receiveText);
Models.WeatherData.RootObject result = JsonConvert.DeserializeObject<Models.WeatherData.RootObject>(receiveText);
cityName.Text = result.city.name;
cityInfo.Text = "Population: " + result.city.population;
listWeather.ItemsSource = result.list;
}
Json数据是从另一个页面传过来的,Root Object反序列化正确。
我添加一个断点来检查它:
但是获取不到对应的测试块绑定数据
我的WeatherInfoPage.xaml中的关键部分是:
<Pivot Title="">
<PivotItem Header="Weather">
<ListView Name="listWeather">
<ListView.Header >
<StackPanel Height="84">
<TextBlock x:Name="cityName" FontSize="35" Height="45"/>
<TextBlock x:Name="cityInfo" FontSize="25" Foreground="Orange" Height="40"></TextBlock>
</StackPanel>
</ListView.Header>
<ListView.ItemTemplate>
<DataTemplate>
<Border Width="360" BorderThickness="2" BorderBrush="#FF2996AE">
<StackPanel>
<TextBlock Text="{Binding time}" FontSize="25"/>
<TextBlock Text="{Binding main}" FontSize="30"></TextBlock>
<StackPanel Orientation="Horizontal">
<Image Stretch="Uniform"
Width="60" Height="60"/>
<Image Stretch="Uniform"
Width="60" Height="60"/>
</StackPanel>
<TextBlock Text="{Binding day}" FontSize="25"></TextBlock>
<TextBlock Text="{Binding night}" FontSize="30"></TextBlock>
</StackPanel>
</Border>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
在我的模拟器中 运行 这个应用程序后,我从调试中得到错误:
Error: BindingExpression path error: 'main' property not found on 'WeatherApp.Models.WeatherData+Day, WeatherApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. BindingExpression: Path='main' DataItem='WeatherApp.Models.WeatherData+Day, WeatherApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'; target element is 'Windows.UI.Xaml.Controls.TextBlock' (Name='null'); target property is 'Text' (type 'String')
Error: BindingExpression path error: 'day' property not found on 'WeatherApp.Models.WeatherData+Day, WeatherApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. BindingExpression: Path='day' DataItem='WeatherApp.Models.WeatherData+Day, WeatherApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'; target element is 'Windows.UI.Xaml.Controls.TextBlock' (Name='null'); target property is 'Text' (type 'String')
Error: BindingExpression path error: 'night' property not found on 'WeatherApp.Models.WeatherData+Day, WeatherApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. BindingExpression: Path='night' DataItem='WeatherApp.Models.WeatherData+Day, WeatherApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'; target element is 'Windows.UI.Xaml.Controls.TextBlock' (Name='null'); target property is 'Text' (type 'String')
而且相应的数据也没有显示在我的列表视图中。
请帮助我,如何从根对象绑定这些数据?非常感谢!
通过在对象中再向下一层来绑定您的数据。
<TextBlock Text="{Binding main}" FontSize="30"></TextBlock>
以上应替换为
<TextBlock Text="{Binding weather[0].main}" FontSize="30"></TextBlock>
这不是您应该复制粘贴 的确切解决方案,但它是一个提示,表明您的UI 设计没有反映您尝试绑定的数据。天气是 list/collection,所以它应该显示在列表视图中而不是文本框中。
试图解释它:-
如果你仔细看,你会发现 time
属性 绑定成功,但不是你的 main 属性。这是因为 main
属性 与 time
属性 不在同一级别,这就是你的异常清楚地告诉你的。
因此,在绑定到任何嵌套 属性 之前,首先尝试查找 属性 在哪个级别可用,然后使用 .
部分级别超过 1.
进行导航。
我正在学习 WP 8.1 应用程序开发,现在正在做一个简单的天气应用程序:我正在读取来自 http://openweathermap.org/ 的天气 Json 数据,Json 数据本身已成功检索,但我无法将数据绑定到我的列表视图。详情如下:
{
"cod": "200",
"message": 0.0907,
"city": {
"id": 658225,
"name": "Helsinki",
"coord": {
"lon": 24.93545,
"lat": 60.169521
},
"country": "FI",
"population": 558457
},
"cnt": 7,
"list": [
{
"dt": 1426413600,
"temp": {
"day": 272.64,
"min": 270.84,
"max": 272.64,
"night": 270.84,
"eve": 272.64,
"morn": 272.64
},
"pressure": 1062.73,
"humidity": 89,
"weather": [
{
"id": 800,
"main": "Clear",
"description": "sky is clear",
"icon": "01d"
}
],
"speed": 5.01,
"deg": 70,
"clouds": 0
},
{
"dt": 1426500000,
"temp": {
"day": 274.26,
"min": 271.16,
"max": 274.26,
"night": 272.43,
"eve": 273.39,
"morn": 271.16
},
"pressure": 1065.67,
"humidity": 90,
"weather": [
{
"id": 800,
"main": "Clear",
"description": "sky is clear",
"icon": "01d"
}
],
"speed": 2.76,
"deg": 78,
"clouds": 0
},
{
"dt": 1426586400,
"temp": {
"day": 274.51,
"min": 272.16,
"max": 274.7,
"night": 272.99,
"eve": 273.9,
"morn": 272.16
},
"pressure": 1062,
"humidity": 92,
"weather": [
{
"id": 800,
"main": "Clear",
"description": "sky is clear",
"icon": "01d"
}
],
"speed": 3.66,
"deg": 170,
"clouds": 0
},
{
"dt": 1426672800,
"temp": {
"day": 274.69,
"min": 272.04,
"max": 275.19,
"night": 272.18,
"eve": 274.77,
"morn": 272.04
},
"pressure": 1056.08,
"humidity": 94,
"weather": [
{
"id": 800,
"main": "Clear",
"description": "sky is clear",
"icon": "01d"
}
],
"speed": 2.02,
"deg": 225,
"clouds": 0
},
{
"dt": 1426759200,
"temp": {
"day": 277.33,
"min": 275.68,
"max": 277.33,
"night": 275.68,
"eve": 276.02,
"morn": 275.87
},
"pressure": 1016.04,
"humidity": 0,
"weather": [
{
"id": 500,
"main": "Rain",
"description": "light rain",
"icon": "10d"
}
],
"speed": 4.95,
"deg": 256,
"clouds": 81,
"rain": 0.47
},
{
"dt": 1426845600,
"temp": {
"day": 275.47,
"min": 271.06,
"max": 275.47,
"night": 271.06,
"eve": 273.94,
"morn": 275.27
},
"pressure": 1027.17,
"humidity": 0,
"weather": [
{
"id": 600,
"main": "Snow",
"description": "light snow",
"icon": "13d"
}
],
"speed": 4.8,
"deg": 30,
"clouds": 92,
"snow": 0.04
},
{
"dt": 1426932000,
"temp": {
"day": 274.33,
"min": 270.47,
"max": 274.33,
"night": 270.47,
"eve": 272.02,
"morn": 270.9
},
"pressure": 1035.35,
"humidity": 0,
"weather": [
{
"id": 800,
"main": "Clear",
"description": "sky is clear",
"icon": "01d"
}
],
"speed": 2.81,
"deg": 84,
"clouds": 3
}
]
}
然后生成天气数据class并参考http://json2csharp.com/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WeatherApp.Models
{
public class WeatherData
{
public class RootObject
{
public string cod { get; set; }
public double message { get; set; }
public City city { get; set; }
public int cnt { get; set; }
public List<Day> list { get; set; }
}
public class Coord
{
public double lon { get; set; }
public double lat { get; set; }
}
public class City
{
public int id { get; set; }
public string name { get; set; }
public Coord coord { get; set; }
public string country { get; set; }
public int population { get; set; }
}
public class Temp
{
public double day { get; set; }
public double min { get; set; }
public double max { get; set; }
public double night { get; set; }
public double eve { get; set; }
public double morn { get; set; }
}
public class Weather
{
public int id { get; set; }
public string main { get; set; }
public string description { get; set; }
public string icon { get; set; }
}
public class Day
{
//public int dt { get; set; }
private int _dt;
public int dt
{
get { return _dt; }
set
{
_dt = value;
var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
time = epoch.AddSeconds(value);
}
}
private DateTime _time;
public DateTime time
{
get { return _time; }
set { _time = value; }
}
public Temp temp { get; set; }
public double pressure { get; set; }
public int humidity { get; set; }
public List<Weather> weather { get; set; }
public double speed { get; set; }
public int deg { get; set; }
public int clouds { get; set; }
public double? rain { get; set; }
public double? snow { get; set; }
}
}
}
来自 WeatherInforPage.xaml.cs:
protected override void OnNavigatedTo(NavigationEventArgs e)
{
this.navigationHelper.OnNavigatedTo(e);
String receiveText = e.Parameter.ToString();
System.Diagnostics.Debug.WriteLine("WeatherInfoPage received handed over weather information: " + receiveText);
Models.WeatherData.RootObject result = JsonConvert.DeserializeObject<Models.WeatherData.RootObject>(receiveText);
cityName.Text = result.city.name;
cityInfo.Text = "Population: " + result.city.population;
listWeather.ItemsSource = result.list;
}
Json数据是从另一个页面传过来的,Root Object反序列化正确。 我添加一个断点来检查它:
但是获取不到对应的测试块绑定数据
我的WeatherInfoPage.xaml中的关键部分是:
<Pivot Title="">
<PivotItem Header="Weather">
<ListView Name="listWeather">
<ListView.Header >
<StackPanel Height="84">
<TextBlock x:Name="cityName" FontSize="35" Height="45"/>
<TextBlock x:Name="cityInfo" FontSize="25" Foreground="Orange" Height="40"></TextBlock>
</StackPanel>
</ListView.Header>
<ListView.ItemTemplate>
<DataTemplate>
<Border Width="360" BorderThickness="2" BorderBrush="#FF2996AE">
<StackPanel>
<TextBlock Text="{Binding time}" FontSize="25"/>
<TextBlock Text="{Binding main}" FontSize="30"></TextBlock>
<StackPanel Orientation="Horizontal">
<Image Stretch="Uniform"
Width="60" Height="60"/>
<Image Stretch="Uniform"
Width="60" Height="60"/>
</StackPanel>
<TextBlock Text="{Binding day}" FontSize="25"></TextBlock>
<TextBlock Text="{Binding night}" FontSize="30"></TextBlock>
</StackPanel>
</Border>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
在我的模拟器中 运行 这个应用程序后,我从调试中得到错误:
Error: BindingExpression path error: 'main' property not found on 'WeatherApp.Models.WeatherData+Day, WeatherApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. BindingExpression: Path='main' DataItem='WeatherApp.Models.WeatherData+Day, WeatherApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'; target element is 'Windows.UI.Xaml.Controls.TextBlock' (Name='null'); target property is 'Text' (type 'String')
Error: BindingExpression path error: 'day' property not found on 'WeatherApp.Models.WeatherData+Day, WeatherApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. BindingExpression: Path='day' DataItem='WeatherApp.Models.WeatherData+Day, WeatherApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'; target element is 'Windows.UI.Xaml.Controls.TextBlock' (Name='null'); target property is 'Text' (type 'String')
Error: BindingExpression path error: 'night' property not found on 'WeatherApp.Models.WeatherData+Day, WeatherApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. BindingExpression: Path='night' DataItem='WeatherApp.Models.WeatherData+Day, WeatherApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'; target element is 'Windows.UI.Xaml.Controls.TextBlock' (Name='null'); target property is 'Text' (type 'String')
而且相应的数据也没有显示在我的列表视图中。 请帮助我,如何从根对象绑定这些数据?非常感谢!
通过在对象中再向下一层来绑定您的数据。
<TextBlock Text="{Binding main}" FontSize="30"></TextBlock>
以上应替换为
<TextBlock Text="{Binding weather[0].main}" FontSize="30"></TextBlock>
这不是您应该复制粘贴 的确切解决方案,但它是一个提示,表明您的UI 设计没有反映您尝试绑定的数据。天气是 list/collection,所以它应该显示在列表视图中而不是文本框中。
试图解释它:-
如果你仔细看,你会发现 time
属性 绑定成功,但不是你的 main 属性。这是因为 main
属性 与 time
属性 不在同一级别,这就是你的异常清楚地告诉你的。
因此,在绑定到任何嵌套 属性 之前,首先尝试查找 属性 在哪个级别可用,然后使用 .
部分级别超过 1.