Страницы

Поиск по вопросам

понедельник, 8 июля 2019 г.

Помогите реализовать обновление данных в WPF

Господа, помогите реализовать грамотное обновление данных.
Работа приложения:
Событие скачивает периодически JSON файл. Подписанным методом на событие читаем с помощью Load(); этот файл и заносим все данные в некую модель. Делаем привязку данных и выводим.
На данный момент имею такой "костыль" (удаляем старую привязку к данным и привязываем по новой):
if (alertbox.ItemsSource != null) alertbox.ItemsSource = null; alertbox.ItemsSource = News.Data.Posts;
Нужно от этого собственно избавится. Пытался реализовать INotifyPropertyChanged, но данные, что бы я не делал, остаются старые...

Собственно сам код:
Загрузка данных из JSON файла (основной метод Read и для удобства статичный Load):
internal class Game { private static GameView Read(string fileName) { GameView data; using (var file = File.OpenText(fileName)) { var serializer = new JsonSerializer(); data = (GameView) serializer.Deserialize(file, typeof(GameView)); }
return data; }
///

/// Основные игровые данные. /// public static GameView Data;
/// /// Загружаем JSON файл с игровыми данными. /// /// Путь до JSON файла public static void Load(string filename = "temp") { if (filename == "temp") filename = $"{Settings.Program.Directories.Temp}/GameData.json"; Data = Read(filename); } }
Модель GameView
public class GameView { public int Version { get; set; } public string MobileVersion { get; set; } public string BuildLabel { get; set; } public int Time { get; set; } public int Date { get; set; } public List Alerts { get; set; } public List ProjectPct { get; set; } public string WorldSeed { get; set; } }
public class Alert { [JsonProperty("_id")] public Id Id { get; set; } public Activation Activation { get; set; } public Expiry Expiry { get; set; } public MissionInfo MissionInfo { get; set; } }
public class MissionInfo { public string MissionType { get; set; } public string Faction { get; set; } public string Location { get; set; } public string LevelOverride { get; set; } public string EnemySpec { get; set; } public int MinEnemyLevel { get; set; } public int MaxEnemyLevel { get; set; } public double Difficulty { get; set; } public int Seed { get; set; } public int MaxWaveNum { get; set; } public MissionReward MissionReward { get; set; } public string ExtraEnemySpec { get; set; } public List CustomAdvancedSpawners { get; set; } public bool? ArchwingRequired { get; set; } public bool? IsSharkwingMission { get; set; } }
Как вызываю:
Game.Load(); alertbox.ItemsSource = Game.Data.Alerts;
Ну и самый простой на данный момент ListBox

Помогите в этом случае реализовать поддержку обновления данных в интерфейсе, как только загрузится JSON файл. Весь проект залит на GitHub


Ответ

Для начала, у вас не получится привязка к полям. Привязка должна быть к свойствам.
Затем, привязка к статическим свойствам неудобна, да и игра — сущность самостоятельная, так что вам имеет смысл сделать методы и свойства класса Game нестатическими. Кроме того, вы должны бы реализовать INotifyPropertyChanged, не вижу этого в вашем коде.
Берём базовый класс VM отсюда, пишем:
internal class Game : VM { private static GameView Read(string fileName) { GameView data; using (var file = File.OpenText(fileName)) { var serializer = new JsonSerializer(); data = (GameView) serializer.Deserialize(file, typeof(GameView)); }
return data; }
GameView data; public GameView Data { get => data; set => Set(ref data, value); }
public void Load(string filename = "temp") { if (filename == "temp") filename = $"{Settings.Program.Directories.Temp}/GameData.json"; Data = Read(filename); } }
Далее, внутренние классы у вас иммутабельные? Если нет, им тоже нужно реализовать INotifyPropertyChanged. А списку нужно реализовывать INotifyCollectionChanged, то есть по идее вам нужна просто ObservableCollection
public class GameView : VM { int version; public int Version { get => version; set => Set(ref version, value); }
// ...
ObservableCollection alerts; public ObservableCollection Alerts { get => alerts; set => Set(ref alerts, value); }
// ... }
и то же самое для остальных классов, к которым вы планируете привязку.
Имея это, можно организовывать привязку в XAML.

Комментариев нет:

Отправить комментарий