You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ListView绑定ViewModel后为空,解析服务器JSON到列表视图遇阻

问题排查与修复方案

我帮你梳理了几个核心问题,这应该就是ListView始终为空的原因:

1. 模型结构与JSON格式不匹配

你的JSON根节点是包含frage数组的对象,但模型层把Frage和RootObject嵌套在Abfahrtskontrolle类内部,同时反序列化时错误地直接将JSON转为IEnumerable<Abfahrtskontrolle>,这会导致反序列化失败,得到的集合为空。

修正模型结构

把模型拆成独立的类,让结构和JSON完全对应:

using System.Collections.Generic;

namespace KD_CHKLST.Models
{
    // 对应JSON中的每个"frage"项
    public class AbfahrtskontrolleFrage
    {
        public string text { get; set; }
        public string description { get; set; }
    }

    // 对应JSON的根对象
    public class AbfahrtskontrolleRoot
    {
        public IEnumerable<AbfahrtskontrolleFrage> frage { get; set; }
    }
}

2. JSON反序列化逻辑错误

在MyHTTP.GetAllNewsAsync中,你没有正确解析JSON的根结构,直接反序列化为IEnumerable<Abfahrtskontrolle>,这会因为结构不匹配返回空集合。

修正HTTP工具类的反序列化代码

using KD_CHKLST.Models;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net.Http;
using System.Threading.Tasks;

namespace KD_CHKLST.Utils
{
    public class MyHTTP
    {
        public static async Task GetAllNewsAsync(Action<IEnumerable<AbfahrtskontrolleFrage>> action)
        {
            using (HttpClient httpClient = new HttpClient()) // 使用using确保资源释放
            {
                try
                {
                    HttpResponseMessage response = await httpClient.GetAsync("http://xxx.xxx.xxx.xxx/chklst.json");
                    response.EnsureSuccessStatusCode(); // 抛出HTTP错误状态异常,方便调试

                    string jsonContent = await response.Content.ReadAsStringAsync();
                    Debug.WriteLine("JSON内容: " + jsonContent);

                    // 先反序列化为根对象,再取出frage数组
                    var root = JsonConvert.DeserializeObject<AbfahrtskontrolleRoot>(jsonContent);
                    Debug.WriteLine("解析到的问题数量: " + (root?.frage?.Count() ?? 0));

                    action(root?.frage ?? new List<AbfahrtskontrolleFrage>());
                }
                catch (Exception ex)
                {
                    Debug.WriteLine("请求或解析错误: " + ex.Message);
                    action(new List<AbfahrtskontrolleFrage>()); // 返回空集合避免崩溃
                }
            }
        }
    }
}

3. ViewModel中的集合类型与模型不匹配

你的ViewModel里Items是ObservableCollection<Abfahrtskontrolle>,但解析得到的是AbfahrtskontrolleFrage集合,需要调整集合类型,同时确保异步操作在UI线程更新集合(避免跨线程更新UI控件的问题)。

修正ViewModel代码

using KD_CHKLST.Models;
using KD_CHKLST.Utils;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Windows.Threading; // WPF环境用这个;UWP用CoreDispatcher

namespace KD_CHKLST.ViewModels
{
    public class AbfahrtskontrolleViewModel : INotifyPropertyChanged
    {
        private ObservableCollection<AbfahrtskontrolleFrage> items;
        public event PropertyChangedEventHandler PropertyChanged;

        public ObservableCollection<AbfahrtskontrolleFrage> Items
        {
            get { return items; }
            set
            {
                items = value;
                OnPropertyChanged(nameof(Items));
            }
        }

        public AbfahrtskontrolleViewModel()
        {
            Items = new ObservableCollection<AbfahrtskontrolleFrage>()
            {
                new AbfahrtskontrolleFrage() { text = "Frage 1", description = "Description 1" },
                new AbfahrtskontrolleFrage() { text = "Frage 2", description = "Description 2" },
            };

            // 异步获取数据,确保在UI线程更新集合
            MyHTTP.GetAllNewsAsync(list =>
            {
                // WPF写法
                Application.Current.Dispatcher.Invoke(() =>
                // UWP写法:Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                {
                    foreach (var item in list)
                    {
                        Items.Add(item);
                        Debug.WriteLine("添加项: " + item.text);
                    }
                });
            });
        }

        // 触发PropertyChanged事件的辅助方法
        protected void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

4. 额外调试建议

  • 调试时查看jsonContent的实际内容,确认是否正确获取到JSON
  • 检查反序列化后的root.frage是否有数据
  • 确保ListView的ItemsSource绑定正确,比如:
    <!-- 假设ViewModel已设置为页面/窗口的DataContext -->
    <ListView ItemsSource="{Binding Items}">
        <ListView.ItemTemplate>
            <DataTemplate>
                <StackPanel>
                    <TextBlock Text="{Binding text}" FontWeight="Bold"/>
                    <TextBlock Text="{Binding description}" Margin="0,4"/>
                </StackPanel>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
    

按照这些步骤修正后,应该就能正确解析JSON并绑定到ListView了。

内容的提问来源于stack exchange,提问作者user8393563

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:26:17