- •Тверской государственный технический университет
- •Сериализация.
- •1. Теоретическая часть.
- •1.1. Сериализация.
- •1.2. Десериализация.
- •1.3. Сериализация коллекций объектов.
- •1.3.1. Описание объекта
- •1.3.2. Роль объектных графов.
- •1.3.3. Настройка объектов для сериализации.
- •1.3.4. Главная форма приложения
- •1.3.5. Настройка фильтра диалогового окна для открытия файлов.
- •2. Указания к выполнению лабораторной работы
- •2.1. Задание на лабораторную работу
- •2.2. Содержание отчета по лабораторной работе
- •Литература:
1.3.4. Главная форма приложения
Для работы с объектами классов, представленных в предыдущих разделах, следует создать Windows-приложение и разместить в ней следующие компоненты:
* Панель, имеющей зеленый цвет фона, на которой разместить следующие компоненты:
- Кнопку для добавления автомобиля в список поставщика
- Статический текст типа Label для вывода надписи "Имя авто"
- Статический текст типа Label для вывода надписи "Макс. скорость"
- Поле однострочного редактора типа TextBox для ввода названия автомобиля
- Поле однострочного редактора типа TextBox для ввода максимальной скорости
* Кнопку для запоминания списка автомобилей в файл
* Кнопку для считывания списка автомобилей из файла
* Средство для визуального отображения данных в виде таблицы типа DataGridView для отображения оригинального списка автомобилей с название carDataGrid
* Средство для визуального отображения данных в виде таблицы типа DataGridView для отображения сохраненного списка автомобилей с названием carDataGrid2.
* Таблицу для хранения данных об автомобилях
Примерный
вид главного окна приложения представлен
на рис.1.
Рис.1. Внешний вид приложения.
Класс формы может иметь следующий вид:
using System;
using System.Data;
using System.Windows.Forms;
using CarGeneralAsm;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization.Formatters.Soap;
using System.Xml.Serialization;
namespace SerializedCarProvider
{
public partial class Form1 : Form
{
CarProvider cp = null, cp = null;
DataTable inventory = null, inventory2 = null;
public Form1()
{
InitializeComponent();
cp=new CarProvider(true);
cp2=new CarProvider(false);
UpdateGrid();
UpdateGrid2();
FormatComboBox.Text = FormatComboBox.Items[0].ToString();
}
private void UpdateGrid()
{
if(cp == null) new CarProvider();
if (inventory == null)
{
// Создаем объект таблицы DataTable с именем Inventory для хранения автомобилей
inventory = new DataTable("Поставщик автомобилей");
// Создаем объекты столбцов DataColumn
DataColumn Name = new DataColumn("Название");
DataColumn Speed = new DataColumn("Скорость");
DataColumn CanFly = new DataColumn("Способность летать");
DataColumn CanSweem = new DataColumn("Способность плавать");
// Добавляем объекты столбцов DataColumn в список DataTable
inventory.Columns.Add(Name);
inventory.Columns.Add(Speed);
inventory.Columns.Add(CanFly);
inventory.Columns.Add(CanSweem);
}
else inventory.Clear();
JamesBondCar c;
// Для каждого автомобиля создаем строку в таблице
for(int i=0; i< cp.GetCarNum(); i++)
{
c = cp.GetJBCByIndex(i);
DataRow newRow = inventory.NewRow();
newRow["Название"] = cp.GetJBCByIndex(i).PetName;
newRow["Скорость"] = cp.GetJBCByIndex(i).MaxSpeed;
newRow["Способность летать"] = cp.GetJBCByIndex(i).CanFly;
newRow["Способность плавать"] = cp.GetJBCByIndex(i).CanSubmerge;
inventory.Rows.Add(newRow);
}
// А теперь указываем объект DataTable в качестве источника данных
// для элемента управления DataGrid
carDataGrid.DataSource = inventory;
}
private void UpdateGrid2()
{
if(cp2 == null || cp == null) new CarProvider();
if (inventory2 == null)
{
// Создаем еще объект таблицы DataTable с именем Inventory2 для хранения
// запомненного списка автомобилей
Inventory2 = new DataTable("Поставщик автомобилей");
// Создаем объекты столбцов DataColumn
DataColumn Name2 = new DataColumn("Название");
DataColumn Speed2 = new DataColumn("Скорость");
DataColumn CanFly2 = new DataColumn("Способность летать");
DataColumn CanSweem2 = new DataColumn("Способность плавать");
// Добавляем объекты столбцов DataColumn в список DataTable
Inventory2.Columns.Add(Name2);
Inventory2.Columns.Add(Speed2);
Inventory2.Columns.Add(CanFly2);
Inventory2.Columns.Add(CanSweem2);
}
else inventory2.Clear();
JamesBondCar c;
if(cp2 == null) return;;
// Для каждого автомобиля создаем строку в таблице
for(int i=0; i< cp2.GetCarNum(); i++)
{
c = cp2.GetJBCByIndex(i);
DataRow newRow = inventory.NewRow();
newRow["Название"] = cp.GetJBCByIndex(i).PetName;
newRow["Скорость"] = cp.GetJBCByIndex(i).MaxSpeed;
newRow["Способность летать"] = cp.GetJBCByIndex(i).CanFly;
newRow["Способность плавать"] = cp.GetJBCByIndex(i).CanSubmerge;
inventory.Rows.Add(newRow);
}
// А теперь указываем объект DataTable в качестве источника данных
// для элемента управления DataGrid
carDataGrid2.DataSource = inventory2;
}
void AddNewCar()
{
cp.AddNewJBCar(NameTextBox.Text, int.Parse(SpeedTextBox.Text),
FlyCheckBox.Checked, SweemCheckBox.Checked);
}
private void AddCarButton_Click(object sender, EventArgs e)
{
if (NameTextBox.Text.Length < 1 && SpeedTextBox.Text.Length < 1) return;
AddNewCar();
if (inventory == null) return;
DataRow newRow = inventory.NewRow();
newRow["Название"] = NameTextBox.Text;
newRow["Скорость"] = int.Parse(SpeedTextBox.Text);
newRow["Способность летать"] = FlyCheckBox.Checked;
newRow["Способность плавать"] = SweemCheckBox.Checked;
inventory.Rows.Add(newRow);
}
private void SaveCarsButton_Click(object sender, EventArgs e)
{
switch (FormatComboBox.Text)
{
case "Бинарный":
FileStream bfs = File.OpenWrite("D:\\Поставщик.dat");
if (bfs == null) return;
BinaryFormatter BFormater = new BinaryFormatter();
BFormater.Serialize(bfs, cp);
bfs.Close(); break;
/*case "SOAP":
Stream sfs = new FileStream("D:\\Поставщик.soap",
FileMode.Create, FileAccess.Write,
FileShare.None | FileShare.Delete);
if(sfs == null) return;
SoapFormatter SFormater = new SoapFormatter();
SFormater.Serialize(sfs, cp);
sfs.Close();
break;*/
case "XML":
Stream xfs = new FileStream("D:\\Поставщик.xml", FileMode.Create,
FileAccess.Write, FileShare.None | FileShare.Delete);
if (xfs == null) return;
XmlSerializer XFormater=new XmlSerializer(typeof(CarProvider),
new Type[] { typeof(JamesBondCar), typeof(Car), typeof(Radio)} );
XFormater.Serialize(xfs, cp);
xfs.Close();
break;
}
}
private void LoadFromFile_Click(object sender, EventArgs e)
{
DialogResult dr = openFileDialog1.ShowDialog();
if (dr != DialogResult.OK) return;
// Очищаем текущий массив
cp.ClearCarList();
string str;
switch (FormatComboBox.Text)
{
case "Бинарный: openFileDialog1.FilterIndex = 1;
str = openFileDialog1.SafeFileName;
FileStream bfs = File.OpenRead(str);
BinaryFormatter bf = new BinaryFormatter();
cp2 = (CarProvider)bf.Deserialize(bfs);
bfs.Close();
break;
case "XML": openFileDialog1.FilterIndex = 2;
str = openFileDialog1.SafeFileName;
FileStream xfs = File.OpenRead(str);
XmlSerializer xf = new XmlSerializer(typeof(CarProvider),
new Type[] {typeof(JamesBondCar), typeof(Car), typeof(Radio)});
cp2 = (CarProvider)xf.Deserialize(xfs);
xfs.Close();
break;
}
UpdateGrid2();
}
}
}
При помощи элементов управления, выведенных на панель зеленого цвета можно формировать описание каждого нового автомобиля и добавлять их в спиcок поставщика.
С помощью клавиши "Запомнить список автомобилей" можно сохранять любое количество автомобилей (объектов типа JamesBondCar), например, так, как показано ниже:
private void SaveCarsButton_Click(object sender, EventArgs e)
{
switch (FormatComboBox.Text)
{
case "Бинарный":
FileStream bfs = File.OpenWrite("D:\\Поставщик.dat");
if (bfs == null) return;
BinaryFormatter BFormater = new BinaryFormatter();
BFormater.Serialize(bfs, cp);
bfs.Close(); break;
case "XML":
Stream xfs = new FileStream("D:\\Поставщик.xml", FileMode.Create,
FileAccess.Write, FileShare.None | FileShare.Delete);
if (xfs == null) return;
XmlSerializer XFormater=new XmlSerializer(typeof(CarProvider),
new Type[] { typeof(JamesBondCar), typeof(Car), typeof(Radio)} );
XFormater.Serialize(xfs, cp);
xfs.Close();
break;
}
}
Поскольку здесь используется XmlSerializer, необходимо указать информацию о типе для каждого из подобъектов внутри корневого объекта (которым в данном случае является List<JamesBondCar>). Если бы применялись типы BinaryFormatter или SoapFormatter, то логика была бы еще проще.
С помощью клавиши "Восстановить список автомобилей" можно восстановить запомненные данные о провайдере и списке имеющихся у него автомобилей, например, так, как показано ниже:
private void LoadFromFile_Click(object sender, EventArgs e)
{
DialogResult dr = openFileDialog1.ShowDialog();
if (dr != DialogResult.OK) return;
// Очищаем текущий массив
cp.ClearCarList();
string str;
switch (FormatComboBox.Text)
{
case "Бинарный: openFileDialog1.FilterIndex = 1;
str = openFileDialog1.SafeFileName;
FileStream bfs = File.OpenRead(str);
BinaryFormatter bf = new BinaryFormatter();
cp2 = (CarProvider)bf.Deserialize(bfs);
bfs.Close();
break;
case "XML": openFileDialog1.FilterIndex = 2;
str = openFileDialog1.SafeFileName;
FileStream xfs = File.OpenRead(str);
XmlSerializer xf = new XmlSerializer(typeof(CarProvider),
new Type[] {typeof(JamesBondCar), typeof(Car), typeof(Radio)});
cp2 = (CarProvider)xf.Deserialize(xfs);
xfs.Close();
break;
}
UpdateGrid2();// Обновить список сохраненных автомобилей
}
Сохранив состояние объекта, можно выключить программу, а при повторном запуске программы восстановить его прежнее состояние. Состояние объектов можно передавать по сети и восстановить их состояние на другом компьютере. Это может пригодиться при выполнении распределенных расчетов, когда объект хранит данные для расчета и которые можно передать на другой компьютер с помощью сериализации.
