【问题标题】:UWP XAML x:Bind not displaying dataUWP XAML x:绑定不显示数据
【发布时间】:2017-10-30 20:31:02
【问题描述】:

对于我的第一个 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 响应反序列化为 Weather 实例)

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; }
    }
}

【问题讨论】:

    标签: c# xaml uwp


    【解决方案1】:

    这是一个快速的答案,只是为了让你开始。您需要通知视图(主页)初始数据已更改。 在 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 并将您的逻辑放在那里而不是代码隐藏。

    【讨论】:

    • 我宁愿建议您不要在 onnavigated 中进行 API 调用。它应该在加载的事件中。因为把它放在 onNavigated to 可能会导致导航和 UI 渲染延迟
    • 直到需要为您的 API 调用检索导航参数,这只能在 OnNavigatedTo 方法中实现。
    猜你喜欢
    • 2018-02-07
    • 1970-01-01
    • 2017-11-13
    • 2020-02-05
    • 1970-01-01
    • 2023-03-30
    • 1970-01-01
    • 1970-01-01
    • 2020-04-07
    相关资源
    最近更新 更多