【问题标题】:Get data out of a JSON string and bind it to XAML从 JSON 字符串中获取数据并将其绑定到 XAML
【发布时间】:2016-08-25 15:09:23
【问题描述】:

编码新手和 JSON 新手,我有这个 JSON 字符串:https://feeds.citibikenyc.com/stations/stations.json

现在我可以得到时间戳,但不能得到像站名这样的数据。

这是我的代理

public class BPNewYorkCityProxy
{
    public async static Task<RootObject> GetNewYorkCity()
    {
        var http = new HttpClient();
        var response = await http.GetAsync("https://feeds.citibikenyc.com/stations/stations.json");
        var result = await response.Content.ReadAsStringAsync();
        var serializer = new DataContractJsonSerializer(typeof(RootObject));

        var ms = new MemoryStream(Encoding.UTF8.GetBytes(result));
        var data = (RootObject)serializer.ReadObject(ms);

        return data;

    }
}

[DataContract]
public class StationBeanList
{
    [DataMember]
    public int id { get; set; }
    [DataMember]
    public string stationName { get; set; }
    [DataMember]
    public int availableDocks { get; set; }
    [DataMember]
    public int totalDocks { get; set; }
    [DataMember]
    public double latitude { get; set; }
    [DataMember]
    public double longitude { get; set; }
    [DataMember]
    public string statusValue { get; set; }
    [DataMember]
    public int statusKey { get; set; }
    [DataMember]
    public int availableBikes { get; set; }
    [DataMember]
    public string stAddress1 { get; set; }
    [DataMember]
    public string stAddress2 { get; set; }
    [DataMember]
    public string city { get; set; }
    [DataMember]
    public string postalCode { get; set; }
    [DataMember]
    public string location { get; set; }
    [DataMember]
    public string altitude { get; set; }
    [DataMember]
    public bool testStation { get; set; }
    [DataMember]
    public string lastCommunicationTime { get; set; }
    [DataMember]
    public string landMark { get; set; }
}

[DataContract]
public class RootObject
{
    [DataMember]
    public string executionTime { get; set; }
    [DataMember]
    public List<StationBeanList> stationBeanList { get; set; }
}

这是我在 XAML 上的代码,如时间戳获取,但现在我想要更多,例如电台名称和可用位置。

private async void GetData_Click(object sender, RoutedEventArgs e)
    {
        RootObject nycParking = await BPNewYorkCityProxy.GetNewYorkCity();

        // how to get a stationname .. my proxy creates a list, does it?... 
        //myStationName.Text = 

        // Well this works
        myTimeStamp.Text = nycParking.executionTime.ToString();

    }

如何做到这一点?提前谢谢

【问题讨论】:

  • 你真的应该考虑使用不同的序列化程序。 Newtonsoft Json.Net 具有比 DataContractJsonSerializer 更好的性能和功能,并且不需要归因于每个单独的类和属性。更不用说它有一个更直观的 API。

标签: c# json xaml data-binding uwp


【解决方案1】:

RootObject 包装了列表 stationBeanList,我想这就是您想要的。

private async void GetData_Click(object sender, RoutedEventArgs e)
{
    RootObject nycParking = await BPNewYorkCityProxy.GetNewYorkCity();

    foreach (var station in nycParking.stationBeanList)
    {
        // Access all of them here may be?
        Console.WriteLine(station.stationName);
    } 

    // Well this works
    myTimeStamp.Text = nycParking.executionTime.ToString();

}

但是如果你想要一个更简单的工作流程,我建议你使用 Json.net,如果这对你来说不是问题

public class BPNewYorkCityProxy
{
    public static async Task<RootObject> GetNewYorkCity()
    {
        var http = new HttpClient();
        var response = await http.GetAsync("https://feeds.citibikenyc.com/stations/stations.json");
        var result = await response.Content.ReadAsStringAsync();
        var data = JsonConvert.DeserializeObject<RootObject>(result);
        return data;
    }
}  
public class StationBeanList
{
    public int id { get; set; }
    public string stationName { get; set; }
    public int totalDocks { get; set; }
    public double latitude { get; set; }
    public double longitude { get; set; }
    public string statusValue { get; set; }
    public int statusKey { get; set; }
    public int availableBikes { get; set; }
    public string stAddress1 { get; set; }
    public string stAddress2 { get; set; }
    public string city { get; set; }
    public string postalCode { get; set; }
    public string location { get; set; }
    public string altitude { get; set; }
    public bool testStation { get; set; }
    public string lastCommunicationTime { get; set; }
    public string landMark { get; set; }
}

public class RootObject
{
    public string executionTime { get; set; }
    public List<StationBeanList> stationBeanList { get; set; }
}

【讨论】:

  • 看起来很干净,Thnx,我会考虑使用 JSON.NET,今天晚些时候会尝试。
  • 使用 JSON.net,更简单,使用来自其他答案的绑定
  • 酷,让我知道你喜欢它。
【解决方案2】:

代理返回列表是正确的

public List<StationBeanList> stationBeanList { get; set; }

由于您有多个列表,因此您无法在单个文本字段中显示它。所以你需要一个清单

<ListBox x:Name="stations"/>

接下来,您需要配置列表中每个元素的外观。在称为 DataTemplate 的 XAML 中。所以让我们为我们的列表配置一个:

<ListBox x:Name="stations">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding stationName}" Margin="5"/>
                <TextBlock Text="{Binding availableDocks}" Margin="5"/>
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

最后,要用结果填充列表,在您的代码隐藏文件中,您需要将列表的 ItemsSource 属性分配给您从服务器获取的数据:

private async void GetData_Click(object sender, RoutedEventArgs e)
{
    RootObject nycParking = await BPNewYorkCityProxy.GetNewYorkCity();

    // how to get a stationname .. my proxy creates a list, does it?... 
    stations.ItemsSource = nycParking.stationBeanList;
    // Well this works
    myTimeStamp.Text = nycParking.executionTime.ToString();
}

这就是全部,它应该适用于您的简单示例。但是,您可能必须处理 XAML 模板并使其看起来更好。您需要处理许多概念并改进代码:

  • 根据数据模型创建视图模型
  • 使用数据绑定将 ListBox itemssource 链接到结果集 (MVVVM)
  • 使用 {x:Bind} 代替旧的 {Binding} - 可选,以提高性能

【讨论】:

  • 问:我还需要创建视图模型吗?有再利用的目的吗?数据绑定我有这个,是的,样式需要工作:),我稍后会尝试这个。
  • 问:关于 x:Bind 然后我需要将 datatemplet 设置为 itemsource。我可以在那里使用 stationBeanList 吗?
  • 我可以再问一个吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-06
  • 1970-01-01
  • 1970-01-01
  • 2014-02-18
相关资源
最近更新 更多