UWP XAML x:绑定不显示数据

时间:2017-10-30 20:31:03

标签: c# xaml uwp

对于我的第一个C#项目,我正在构建一个通用Windows平台天气应用程序,用于从Yahoo! weather API检索数据。应用程序的这一部分工作正常。我目前坚持的部分是使用x:Bind将数据绑定到用户界面。

不幸的是我不知道我做错了什么,因为在Visual Studio中没有返回错误消息。我非常感谢你的帮助:)。

MainPage.xaml.cs中:

namespace WeatherPanel
{
    public sealed partial class MainPage : Page
    {
        public Weather Weather { get; set; }
        static HttpClient client = new HttpClient();

        private async void GetData()
        {
            // Get latitude, longitude, and other IP-related data.
            IP ip = await Task.Run(() => GetIP());

            // Get current weather and forecast.
            string weather_url = BuildWeatherUrl("forecast", ip.lat, ip.lon);
            this.Weather = await Task.Run(() => GetWeather(weather_url));

            // This works, so we know we're getting weather data.
            // Debug.WriteLine("--- Distance = " + this.Weather.query.results.channel.units.distance);
        }

        public MainPage()
        {
            // Initializes the GUI: sets up buttons, labels, event handlers, etc.
            this.InitializeComponent();
            this.Weather = new Weather();

            // Get location and weather. Meanwhile, execution continues so UI thread isn't blocked.
            GetData();
        }
    }
}

MainPage.xaml中:

<Page
    x:Class="WeatherPanel.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:WeatherPanel"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">
    <Grid>
        <!-- ... -->
        <Grid Name="gd_forecast" Grid.Row="2" VerticalAlignment="Top" HorizontalAlignment="Center">
            <Grid.ColumnDefinitions>
                <!-- ... -->
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <!-- ... -->
            </Grid.RowDefinitions>
            <!-- This is not working: -->
            <TextBlock Grid.Column="0" Grid.Row="0" Text="{x:Bind Weather.query.results.channel.units.distance}"/>
        </Grid>
    </Grid>
</Page>

weather.cs(GetWeather()反序列化对天气实例的JSON响应)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WeatherPanel
{
    public class Units
    {
        public string distance { get; set; }
        public string pressure { get; set; }
        public string speed { get; set; }
        public string temperature { get; set; }
    }

    public class Location
    {
        public string city { get; set; }
        public string country { get; set; }
        public string region { get; set; }
    }

    public class Wind
    {
        public string chill { get; set; }
        public string direction { get; set; }
        public string speed { get; set; }
    }

    public class Atmosphere
    {
        public string humidity { get; set; }
        public string pressure { get; set; }
        public string rising { get; set; }
        public string visibility { get; set; }
    }

    public class Astronomy
    {
        public string sunrise { get; set; }
        public string sunset { get; set; }
    }

    public class Image
    {
        public string title { get; set; }
        public string width { get; set; }
        public string height { get; set; }
        public string link { get; set; }
        public string url { get; set; }
    }

    public class Condition
    {
        public string code { get; set; }
        public string date { get; set; }
        public string temp { get; set; }
        public string text { get; set; }
    }

    public class Forecast
    {
        public string code { get; set; }
        public string date { get; set; }
        public string day { get; set; }
        public string high { get; set; }
        public string low { get; set; }
        public string text { get; set; }
    }

    public class Guid
    {
        public string isPermaLink { get; set; }
    }

    public class Item
    {
        public string title { get; set; }
        public string lat { get; set; }
        public string @long { get; set; }
        public string link { get; set; }
        public string pubDate { get; set; }
        public Condition condition { get; set; }
        public List<Forecast> forecast { get; set; }
        public string description { get; set; }
        public Guid guid { get; set; }
    }

    public class Channel
    {
        public Units units { get; set; }
        public string title { get; set; }
        public string link { get; set; }
        public string description { get; set; }
        public string language { get; set; }
        public string lastBuildDate { get; set; }
        public string ttl { get; set; }
        public Location location { get; set; }
        public Wind wind { get; set; }
        public Atmosphere atmosphere { get; set; }
        public Astronomy astronomy { get; set; }
        public Image image { get; set; }
        public Item item { get; set; }
    }

    public class Results
    {
        public Channel channel { get; set; }
    }

    public class Query
    {
        public int count { get; set; }
        public DateTime created { get; set; }
        public string lang { get; set; }
        public Results results { get; set; }
    }

    public class Weather
    {
        public Query query { get; set; }
    }
}

1 个答案:

答案 0 :(得分:3)

这是快速回答,只是为了让你前进。您需要通知视图(主页)初始数据已更改。 在MainPage中实现INotifyPropertyChanged接口,然后在每次值更改时引发事件。

namespace WeatherPanel
{
    public sealed partial class MainPage : Page, INotifyPropertyChanged
    {
        public Weather Weather { get; set; }
        static HttpClient client = new HttpClient();

        private async void GetData()
        {
        // Get latitude, longitude, and other IP-related data.
        IP ip = await Task.Run(() => GetIP());

        // Get current weather and forecast.
        string weather_url = BuildWeatherUrl("forecast", ip.lat, ip.lon);
        this.Weather = await Task.Run(() => GetWeather(weather_url));

        // This works, so we know we're getting weather data.
        // Debug.WriteLine("--- Distance = " + this.Weather.query.results.channel.units.distance);
        }

        public MainPage()
        {
        // Initializes the GUI: sets up buttons, labels, event handlers, etc.
        this.InitializeComponent();
        this.Weather = new Weather();

        // Get location and weather. Meanwhile, execution continues so UI thread isn't blocked.
        GetData();
        NotifyPropertyChanged(nameof(Weather)); //Raise the event
        }
        //the event to raise on changes
        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

然后将绑定模式设置为 OneWay ,如下所示:

<TextBlock Grid.Column="0" Grid.Row="0" Text="{x:Bind  Weather.query.results.channel.units.distance, Mode=OneWay}"/>

但是我建议您在OnNavigatedTo方法中运行对API的异步调用,而不是构造函数。 尝试使用MVVM pattern将视图绑定到ViewModel并将逻辑放在那里而不是代码隐藏。