Сериализация и десериализация файла формата json в Avalonia MVVM
Возникла проблема с сериализацией и десериализацией файла json в avalonia. Имеется коллекция, и ее объекты необходимо сохранить в файл, и затем этот же файл открыть чтобы объекты появились на экране. Необходимо сделать через файловый менеджер. Также есть свойство не связанное с коллекцией, но в связи с ним меняется условие создания новых элементов коллекции, оно указано в комбобоксе.
View:
<StackPanel>
<StackPanel Orientation="Horizontal">
<ComboBox ItemsSource="{Binding Brand}" SelectedValue="{Binding CurrentBrand}"/>
<Button Content="Add new row" Command="{Binding AddNewRow}"/>
<Button Content="Save" Command="{Binding SaveFile}"/>
<Button Content="Open file" Command="{Binding OpenFile}"/>
</StackPanel>
<ItemsControl ItemsSource="{Binding CarList}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" Margin="10">
<TextBlock TextAlignment="Center" VerticalAlignment="Center" Width="50" Text="{Binding Id}"/>
<TextBox Text="{Binding Model}"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
models:
private int _id;
private string _model;
public int Id
{
get => _id;
set => this.RaiseAndSetIfChanged(ref _id, value);
}
public string Model
{
get => _model;
set => this.RaiseAndSetIfChanged(ref _model, value);
}
VM:
public class MainWindowViewModel : ViewModelBase
{
private ObservableCollection<Car> _carList;
public ObservableCollection<Car> CarList
{
get => _carList;
set => this.RaiseAndSetIfChanged(ref _carList, value);
}
public ReactiveCommand<Unit, Unit> AddNewRow { get; set; }
public ReactiveCommand<Unit, Unit> SaveFile { get; set; }
public ReactiveCommand<Unit, Unit> OpenFile { get; set; }
private string _currentBrand;
public string CurrentBrand
{
get => _currentBrand;
set
{
CarList.Clear();
this.RaiseAndSetIfChanged(ref _currentBrand, value);
}
}
public ObservableCollection<string> _brand;
public ObservableCollection<string> Brand
{
get => _brand;
set => this.RaiseAndSetIfChanged(ref _brand, value);
}
public MainWindowViewModel()
{
Brand = new ObservableCollection<string>();
Brand.Add("BMW");
Brand.Add("Audi");
CarList = new ObservableCollection<Car>(new List<Car>());
AddNewRow = ReactiveCommand.Create(() =>
{
if (CurrentBrand == Brand[0])
{
CarList.Add(
new()
{
Id = CarList.Count + 1,
Model = "X5M",
});
}
else if (CurrentBrand == Brand[1])
{
CarList.Add(
new()
{
Id = CarList.Count + 1,
Model = "RS6",
});
}
else
{
CarList.Add(
new()
{
Id = CarList.Count + 1,
Model = "Не выбран бренд",
});
}
});
SaveFile = ReactiveCommand.Create(() =>
{
}
OpenFile = ReactiveCommand.Create(() =>
{
}
Ответы (1 шт):
Автор решения: Mikhail
→ Ссылка
Вот собственное решение, подскажите в чем проблема, на вскидку все работает.
MODELS:
public class Car: ViewModelBase
{
private int _id;
private string _model;
private string _brand;
[DataMember]
public int Id
{
get => _id;
set => this.RaiseAndSetIfChanged(ref _id, value);
}
[DataMember]
public string Model
{
get => _model;
set => this.RaiseAndSetIfChanged(ref _model, value);
}
[DataMember]
public string Brand
{
get => _brand;
set => this.RaiseAndSetIfChanged(ref _brand, value);
}
VM:
public class MainWindowViewModel : ViewModelBase
{
private ObservableCollection<Car> _carList;
[XmlArray("Collection"), XmlArrayItem("Item")]
public ObservableCollection<Car> CarList
{
get => _carList;
set => this.RaiseAndSetIfChanged(ref _carList, value);
}
public ReactiveCommand<Unit, Unit> AddNewRow { get; set; }
public ReactiveCommand<Unit, Unit> SaveFile { get; set; }
public ReactiveCommand<Unit, Unit> OpenFile { get; set; }
private string _currentBrand;
public string CurrentBrand
{
get => _currentBrand;
set
{
CarList.Clear();
this.RaiseAndSetIfChanged(ref _currentBrand, value);
}
}
public ObservableCollection<string> _brand;
public ObservableCollection<string> Brand
{
get => _brand;
set => this.RaiseAndSetIfChanged(ref _brand, value);
}
public MainWindowViewModel()
{
Brand = new ObservableCollection<string>();
Brand.Add("BMW");
Brand.Add("Audi");
CarList = new ObservableCollection<Car>(new List<Car>());
AddNewRow = ReactiveCommand.Create(() =>
{
if (CurrentBrand == Brand[0])
{
CarList.Add(
new()
{
Id = CarList.Count + 1,
Model = "X5M",
Brand = CurrentBrand
});
}
else if (CurrentBrand == Brand[1])
{
CarList.Add(
new()
{
Id = CarList.Count + 1,
Model = "RS6",
Brand = CurrentBrand
});
}
else
{
CarList.Add(
new()
{
Id = CarList.Count + 1,
Model = "Не выбран бренд",
Brand = null!
});
}
});
SaveFile = ReactiveCommand.Create(() =>
{
// XmlSerializer xs = new XmlSerializer(typeof(ObservableCollection<Car>));
// using (StreamWriter wr = new StreamWriter(@"C:\Users\Mikhail\Desktop\Cars.xml"))
// {
// xs.Serialize(wr, CarList);
// }
SaveJsonFile();
});
OpenFile = ReactiveCommand.Create(OpenJsonFile);
}
string _path;
private static FilePickerFileType Json { get; } = new("All xls")
{
Patterns = new[]
{
"*.elegir",
"*.json"
},
MimeTypes = null,
AppleUniformTypeIdentifiers = null,
};
private async void OpenJsonFile()
{
var topLevel = TopLevel.GetTopLevel(new MainWindow());
var files = await topLevel.StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
{
Title = "Open Json File",
AllowMultiple = false,
FileTypeFilter = new[] { Json },
SuggestedStartLocation = await topLevel.StorageProvider.TryGetFolderFromPathAsync("C:\\")
});
if (files.Count >= 1)
{
// Open reading stream from the first file.
await using var stream = await files[0].OpenReadAsync();
using var streamReader = new StreamReader(stream);
ObservableCollection<Car> deserialize = JsonConvert.DeserializeObject<ObservableCollection<Car>>(streamReader.ReadLine());
CurrentBrand = deserialize[0].Brand;
CarList = deserialize;
}
}
private async void SaveJsonFile()
{
var topLevel = TopLevel.GetTopLevel(new MainWindow());
var file = await topLevel.StorageProvider.SaveFilePickerAsync(new FilePickerSaveOptions
{
Title = "Save Json File",
FileTypeChoices = new [] { Json },
SuggestedStartLocation = await topLevel.StorageProvider.TryGetFolderFromPathAsync("C:\\"),
SuggestedFileName = CurrentBrand + "-" + DateTime.Now.ToString("dd.MM.yyyy") + ".elegir",
});
if (file is not null)
{
// Open writing stream from the file.
await using var stream = await file.OpenWriteAsync();
using var streamWriter = new StreamWriter(stream);
// Write some content to the file.
string serialized = JsonConvert.SerializeObject(CarList);
streamWriter.WriteLine(serialized);
}
// File.WriteAllText("SuperFile.json", JsonSerializer.Serialize(CarList));
}
}
Json файл:
[{"Model":"X5M","Id":1,"Brand":"BMW"},{"Model":"X5M","Id":2,"Brand":"BMW"},{"Model":"X5M","Id":3,"Brand":"BMW"},{"Model":"X5M","Id":4,"Brand":"BMW"}]