VB.NET XmlSerializer を使ってフォームをシリアル化
(Visual Studio 2015 版)

投稿日 2016/04/13

[Home] 

概要

XmlSerializer クラスを使うと簡単にオブジェクトをシリアライズして XML ファイルを生成してくれます。逆にその XML ファイルを逆シリアル化してオブジェクトを復元できます。ところが、複雑なオブジェクトではシリアル化に失敗してしまうこともあります。

フォーム (System.Windows.Forms.Form) では多くのコントロールやプロパティが含まれているので、そのままシリアル化すると失敗してしまいます。また、シリアル化したくないものもたいてい含まれています。

次のサンプルでは、直接フォームをシリアル化するのではなくて、いったん中間的なクラスにフォームのデータを保存してそのクラスをシリアル化しています。このようにすれば手間はかかりますがシリアル化に失敗することはありません。この中間クラスには、単純な型のデータのみをいれるようにします。複雑な型が含まれているとフォームと同じようにシリアル化できないこともあります。

 

XmlSerializer の使い方

XmlSerializer クラスは System.Xml.Serialization 名前空間に含まれるクラスです。したがって、この名前空間を Imports で宣言しておく必要があります。

このクラスで直接 I/O するわけではなく、他の I/O を行うクラス (例: FileStream) を利用します。したがって、このようなクラスのインスタンスを用意しておく必要があります。さらに、シリアル化するオブジェクトの Type オブジェクトが必要になります。これは、GetType 演算子で取得できます。

 

サンプル

次のサンプルはいくつかのコントロールを持つフォーム (Form1) のシリアル化と逆シリアル化を行うものです。



XmlSerializeClass クラス

Imports System.IO
Imports System.Xml.Serialization

''' <summary>
''' シリアライズクラス
''' </summary>
Public Class XmlSerializeClass
    ''' <summary>
    ''' XML シリアライズ
    ''' </summary>
    ''' <typeparam name="T">オブジェクトの型</typeparam>
    ''' <param name="filePath">保存先のファイル名</param>
    ''' <param name="obj">シリアライズするオブジェクト</param>
    Public Shared Sub SaveTo(Of T)(ByVal filePath As String, ByVal obj As T)
        Dim xs As XmlSerializer
        Using stream As FileStream = File.Open(filePath, FileMode.Create)
            xs = New XmlSerializer(GetType(T))
            xs.Serialize(stream, obj)
        End Using
    End Sub

    ''' <summary>
    ''' XML 逆シリアライズ
    ''' </summary>
    ''' <typeparam name="T">オブジェクトの型</typeparam>
    ''' <param name="filePath">読み込むファイル名</param>
    ''' <returns>逆シリアライズされたオブジェクト</returns>
    Public Shared Function LoadFrom(Of T)(ByVal filePath As String) As T
        Dim xs As XmlSerializer
        Dim obj As T
        Using stream As FileStream = File.Open(filePath, FileMode.Open)
            xs = New XmlSerializer(GetType(T))
            obj = xs.Deserialize(stream)
        End Using
        Return obj
    End Function
End Class

シリアライズ対象のフォーム Form1

Imports XmlSerialyzer
Imports System.Xml.Serialization

Public Class Form1
    ' XML ファイルのパス名
    Const XMLFILE As String = "C:\temp\Form1.xml"

    ''' <summary>
    ''' フォームのデータを保持するクラス
    ''' </summary>
    Public Class TSerialyzed
        <XmlIgnoreAttribute()>
        Public FSuccess As Boolean  ' シリアライズ成功フラグ(この値は対象外にしている)   
        Public TextBox1Text As String
        Public TextBox2Text As String
        Public CheckBox1Checked As Boolean
        Public ComboBox1Items As String()
        Public ComboBox1SelectedIndex As Integer

        ''' <summary>
        ''' コンストラクタ
        ''' </summary>
        ''' <remarks>デフォルトコンストラクタが必要</remarks>
        Public Sub New()
            FSuccess = False
            TextBox1Text = ""
            TextBox2Text = ""
            CheckBox1Checked = False
            ComboBox1Items = {}
            ComboBox1SelectedIndex = -1
        End Sub

        ''' <summary>
        ''' フォームの現在の値をオブジェクトにコピーする。
        ''' </summary>
        ''' <param name="frm"></param>
        Public Sub CopyValues(ByVal frm As Form1)
            TextBox1Text = frm.TextBox1.Text
            TextBox2Text = frm.TextBox2.Text
            CheckBox1Checked = frm.CheckBox1.Checked
            Dim items As New List(Of String)
            For Each item As String In frm.ComboBox1.Items
                items.Add(item)
            Next
            ComboBox1Items = items.ToArray()
            ComboBox1SelectedIndex = frm.ComboBox1.SelectedIndex
        End Sub

        ''' <summary>
        ''' 現在の値を Form1 のコントロールに設定する。
        ''' </summary>
        ''' <param name="frm"></param>
        Public Sub Recover(ByVal frm As Form1)
            frm.TextBox1.Text = TextBox1Text
            frm.TextBox2.Text = TextBox2Text
            frm.CheckBox1.Checked = CheckBox1Checked
            frm.ComboBox1.Items.AddRange(ComboBox1Items)
            frm.ComboBox1.SelectedIndex = ComboBox1SelectedIndex
        End Sub
    End Class

    ''' <summary>
    ''' フォームがロードしたとき
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        If Not System.IO.File.Exists(XMLFILE) Then
            Exit Sub
        End If

        Dim obj As TSerialyzed
        Try
            obj = XmlSerializeClass.LoadFrom(Of TSerialyzed)(XMLFILE)
            obj.Recover(Me)
        Catch ex As Exception
            MessageBox.Show(ex.Message, "例外を検出", MessageBoxButtons.OK, MessageBoxIcon.Hand)
        End Try
    End Sub

    ''' <summary>
    ''' シリアライズボタン
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim obj As New TSerialyzed
        Try
            obj.CopyValues(Me)
            XmlSerializeClass.SaveTo(XMLFILE, obj)
            obj.FSuccess = True
            MessageBox.Show(XMLFILE & "に保存しました。", "結果", MessageBoxButtons.OK, MessageBoxIcon.Information)
        Catch ex As Exception
            obj.FSuccess = False
            MessageBox.Show(ex.Message, "例外を検出", MessageBoxButtons.OK, MessageBoxIcon.Hand)
        End Try
    End Sub

    ''' <summary>
    ''' Add ボタン
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
        ComboBox1.Items.Add("Item " & ComboBox1.Items.Count)
    End Sub

    ''' <summary>
    ''' クリアボタン
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
        ComboBox1.Items.Clear()
    End Sub

    ''' <summary>
    ''' Close ボタン
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
        Close()
    End Sub
End Class








 

 


 

 開設 2014年12月   著作権 2014-2015 bonk.red  連絡先: こちらからメッセージを送ってください。

 このページの先頭へ..