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.

进行导航。