Господа, помогите реализовать грамотное обновление данных.
Работа приложения:
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;
}
/// <summary>
/// Основные игровые данные.
/// </summary>
public static GameView Data;
/// <summary>
/// Загружаем JSON файл с игровыми данными.
/// </summary>
/// <param name="filename">Путь до JSON файла</param>
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<Alert> Alerts { get; set; }
public List<double> 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<string> CustomAdvancedSpawners { get; set; }
public bool? ArchwingRequired { get; set; }
public bool? IsSharkwingMission { get; set; }
}
Как вызываю:
Game.Load();
alertbox.ItemsSource = Game.Data.Alerts;
Ну и самый простой на данный момент ListBox
:
<ListBox x:Name="alertbox" Background="{x:Null}" BorderBrush="{x:Null}">
<ListBox.ItemTemplate>
<DataTemplate >
<Label Content="{Binding MissionInfo.Location}" />
</DataTemplate>
</ListBox.ItemTemplate>
</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<T>
:
public class GameView : VM
{
int version;
public int Version
{
get => version;
set => Set(ref version, value);
}
// ...
ObservableCollection<Alert> alerts;
public ObservableCollection<Alert> Alerts
{
get => alerts;
set => Set(ref alerts, value);
}
// ...
}
и то же самое для остальных классов, к которым вы планируете привязку.
Имея это, можно организовывать привязку в XAML.
<ListBox Background="{x:Null}" BorderBrush="{x:Null}" ItemsSource="{Binding Data.Alerts}">
<ListBox.ItemTemplate>
<DataTemplate >
<Label Content="{Binding MissionInfo.Location}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Открываю из программы картинку в стандартном "Просмотр фотографий Windows" таким образом:
Необходимо заполнить dataGrid двумерным массивом строки все бы было просто если бы не паттерн
Может я что-то не так понимаю, но суть в чемЯ пишу библиотеку, ее нельзя скомпилить напрямую как мне подсказала студия, поэтому я создал проект...