Windows phone 8.1 将数据从数据源(HUB 模板)绑定到 XAML

Windows phone 8.1 binding data to XAML from datasource (HUB template)

我需要帮助...

基本上我一直在看 WP 8.1 开发教程并且有一个带有标准 HUB 模板的教程。

所以我尝试配置这个模板供我自己使用。我有一个 JSON 文件,其中包含我需要的所有数据(公寓),我现在想在我的页面上列出这些数据。我 "recreated" 我的应用程序中的 SampleDataSource 只是 DataSource。我认为数据一切正常,现在出现了转换此数据并将其绑定到 XAML 的问题。我真的不知道为什么它不起作用,因为我刚刚尝试更改在模板(由 SDK 提供)中工作的参数。你们能帮帮我吗?或者给我一些指导,我在哪里可以找到这样做的例子。

如果有人愿意帮助或 skype/TW 只是为了向我展示结构和我必须做的事情,我将不胜感激,因为我会知道这基本上是如何翻译和工作的,所以我可以处理项目的其他部分!有比特币作为奖励! :)

提前致谢。

编辑:添加 Github 回购:https://github.com/lklancir/zimmerfrei_wp/tree/master/ZimmerFrei_v0.1

这里是DataSource.cs:

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Data.Json;
using Windows.Storage;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Imaging;

命名空间ZimmerFrei.Data {

public class ApartmentData
{
    public ApartmentData(String id, String name, String description, String capacity, String stars, String address, String email, String phone, String phone2, String rating, String lat, String lng, String price, String cover_photo, String owner_id, String type_id, String city_id)
    {
        this.Id = id;
        this.Name = name;
        this.Description = description;
        this.Capacity = capacity;
        this.Stars = stars;
        this.Address = address;
        this.Email = email;
        this.Phone = phone;
        this.Phone2 = phone2;
        this.Rating = rating;
        this.Lat = lat;
        this.Lng = lng;
        this.Price = price;
        this.Cover_photo = cover_photo;
        this.Owner_id = owner_id;
        this.Type_id = type_id;
        this.City_id = city_id;


    }

    public string Id { get; private set; }
    public string Name { get; private set; }
    public string Description { get; private set; }
    public string Capacity { get; private set; }
    public string Stars { get; private set; }
    public string Address { get; private set; }
    public string Email { get; private set; }
    public string Phone { get; private set; }
    public string Phone2 { get; private set; }
    public string Rating { get; private set; }
    public string Lat { get; private set; }
    public string Lng { get; private set; }
    public string Price { get; private set; }
    public string Cover_photo { get; private set; }
    public string Owner_id { get; private set; }
    public string Type_id { get; private set; }
    public string City_id { get; private set; }

    public override string ToString()
    {
        return this.Name;
    }
}



public sealed class DataSource
{
    private static DataSource _dataSource = new DataSource();

    private ObservableCollection<ApartmentData> _apartments = new ObservableCollection<ApartmentData>();

    public ObservableCollection<ApartmentData> Apartments
    {
        get { return this._apartments; }
    }

    public static async Task<IEnumerable<ApartmentData>> GetApartmentsAsync()
    {   
        await _dataSource.GetDataAsync();

        return _dataSource.Apartments;
    }

    public static async Task<ApartmentData> GetApartmentAsync(string id)
    {
        await _dataSource.GetDataAsync();
        var matches = _dataSource.Apartments.Where((apartment) => apartment.Id.Equals(id));
        if (matches.Count() == 1) return matches.First();
        return null;
    }



    private async Task GetDataAsync()
    {
        if (this._apartments.Count != 0)
            return;

        Uri dataUri = new Uri("ms-appx:///DataModel/Apartments.json");
        StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(dataUri);
        string jsonText = await FileIO.ReadTextAsync(file);
        JsonObject jsonObject = JsonObject.Parse(jsonText);
        JsonArray jsonArray = jsonObject["apartments"].GetArray();

        foreach (JsonValue apartmentValue in jsonArray)
        {
            JsonObject apartmentObject = apartmentValue.GetObject();
            ApartmentData apartment = new ApartmentData(apartmentObject["Id"].GetString(),
                                                        apartmentObject["Name"].GetString(),
                                                        apartmentObject["Description"].GetString(),
                                                        apartmentObject["Capacity"].GetString(),
                                                        apartmentObject["Stars"].GetString(),
                                                        apartmentObject["Address"].GetString(),
                                                        apartmentObject["Email"].GetString(),
                                                        apartmentObject["Phone"].GetString(),
                                                        apartmentObject["Phone2"].GetString(),
                                                        apartmentObject["Rating"].GetString(),
                                                        apartmentObject["Lat"].GetString(),
                                                        apartmentObject["Lng"].GetString(),
                                                        apartmentObject["Price"].GetString(),
                                                        apartmentObject["Cover_photo"].GetString(),
                                                        apartmentObject["Owner_id"].GetString(),
                                                        apartmentObject["Type_id"].GetString(),
                                                        apartmentObject["City_id"].GetString());

            this.Apartments.Add(apartment);
        }
    }
}

}

这里是ListPage.xaml(我想写出我的数据的地方)

<Page
x:Class="ZimmerFrei_v0._1.ListPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:ZimmerFrei_v0._1"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:data="using:ZimmerFrei.Data"
DataContext="{Binding DefaultViewModel, RelativeSource={RelativeSource Self}}"
d:DataContext="{Binding Source={d:DesignData Source=/DataModel/Apartments.json, Type=data:DataSource}}"
mc:Ignorable="d" FontFamily="Global User Interface">


<Page.Resources>


<DataTemplate x:Key="StandardTripleLineItemTemplate">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>

        <Border Background="{ThemeResource ListViewItemPlaceholderBackgroundThemeBrush}" Margin="0,9.5,0,0" Grid.Column="0" HorizontalAlignment="Left">
            <Image Source="{Binding Cover_photo}" Stretch="UniformToFill" AutomationProperties.Name="{Binding Title}" Height="79" Width="79"/>
        </Border>
        <StackPanel Grid.Column="1" Margin="14.5,0,0,0">
            <TextBlock Text="{Binding Name}" Style="{ThemeResource ListViewItemTextBlockStyle}" FontFamily="Global User Interface"/>
            <TextBlock Text="{Binding Description}" Style="{ThemeResource ListViewItemContentTextBlockStyle}" Foreground="{ThemeResource PhoneMidBrush}" FontFamily="Global User Interface" />
            <TextBlock Text="{Binding Stars}" Style="{ThemeResource ListViewItemSubheaderTextBlockStyle}" />
        </StackPanel>
    </Grid>
</DataTemplate>

</Page.Resources>

<Grid x:Name="LayoutRoot">
    <Hub x:Name="Hub" x:Uid="Hub" Header="ZimmerFrei">

        <HubSection x:Uid="HubSection" Header="APARTMENTS"
                    DataContext="{Binding Apartments}" >
            <DataTemplate>
                <ListView 
                    AutomationProperties.AutomationId="ItemListViewSection3"
                    AutomationProperties.Name="Items In Group"
                    SelectionMode="None"
                    IsItemClickEnabled="True"
                    ItemsSource="{Binding apartment}"
                    ItemTemplate="{StaticResource StandardTripleLineItemTemplate}"
                    ItemClick="ItemView_ItemClick"
                    ContinuumNavigationTransitionInfo.ExitElementContainer="True">
                </ListView>
            </DataTemplate>
        </HubSection>
    </Hub>
</Grid>

这里有几个问题:

  • 您的 ApartmentData class 有一些这样命名的属性 Cover_photo。这通常不是 C# 使用的样式约定,因此我将它们重命名为 like CoverPhoto.
  • 在同一主题上,您的 ApartmentData 属性被命名为 Cover_photo 但它们在 JSON 中被命名为 cover_photo (这是典型的 JSON 风格)。您正在像这样访问 JSON 键:

    apartmentObject["Cover_photo"].GetString()  // KeyNotFoundException
    

    但应该是:

    apartmentObject["cover_photo"].GetString()
    

    这将在运行时运行,设计人员不会执行此代码。设计器读取 JSON 文件并尝试将 JSON 文件中的键与您指定的类型的属性相匹配,但它无法匹配,因为键和属性不匹配。所以要么你:

    1. 修改 JSON 使键匹配 CoverPhoto.
    2. 等属性
    3. DataContractAttribute. This allows you to specify the mapping between JSON and .NET type with DataMemberAttribute 注释你的类型,但主要是因为你得到 JSON serialization/deserialization!

我向您发送了包含这些更改的拉取请求。此外,您的设计数据非常庞大(约 1000 项!)。它应该只包含 ~5 个项目,因为无论如何您都无法在设计器中看到所有项目。