DOBON.NET プログラミング道: .NET Framework, VB.NET, C#, Visual Basic, Visual Studio, インストーラ, ...

ApplicationSettingsBaseクラスを使って設定を保存する

注意:ApplicationSettingsBaseクラスは.NET Framework 2.0以降でのみ使用できます。

Visual Studioでアプリケーションの設定を保存する」では、Visual Studioを使って設定を保存する方法を紹介しました。ここではVisual Studioを使わずに、設定を保存する方法を紹介します。

なおこの記事は、「Visual Studioでアプリケーションの設定を保存する」でできることをVisual Studioを使わずに行うことを目的としますので、もし「Visual Studioでアプリケーションの設定を保存する」をまだお読みでなければ、まずそちらをご覧ください。また、Visual Studioを使用する方法より難易度が上がりますので、初心者の方にはVisual Studioを使用する方法をお勧めします。

設定を作成する

まず、ユーザースコープの設定を作成してみましょう(スコープについては、こちらで説明しています)。ここでは、"Message"という名前のString型の設定を作成します。

それには、ApplicationSettingsBaseクラスを継承したクラスを作成し、"Message"というプロパティを追加します(このクラスを「アプリケーション設定クラス」、プロパティを「アプリケーション設定プロパティ」と呼びます)。そして、ユーザースコープとするために、UserScopedSettingAttribute属性を適用します。具体的には、次のようなコードになります。

VB.NET
コードを隠すコードを選択
Imports System.Configuration

Public Class TestSettings
    Inherits ApplicationSettingsBase

    <UserScopedSetting()> _
    Public Property Message() As String
        Get
            Return CStr(Me("Message"))
        End Get
        Set(ByVal value As String)
            Me("Message") = value
        End Set
    End Property
End Class
C#
コードを隠すコードを選択
using System.Configuration;

public class TestSettings : ApplicationSettingsBase
{
    [UserScopedSetting()]
    public string Message
    {
        get
        {
            return (string)this["Message"];
        }
        set
        {
            this["Message"] = value;
        }
    }
}

TestSettingsクラスの使い方は、「Visual Studioでアプリケーションの設定を保存する」で紹介したMySettings(C#では、Settings)クラスと同じです。ただし、インスタンスは自分で作成する必要があります。

以下の例では、Button1をクリックしたときに設定"Message"をTextBox1に表示し、Button2をクリックしたときにTextBox1の内容を設定"Message"に格納してから保存しています。

VB.NET
コードを隠すコードを選択
'設定
Dim appSettings As New TestSettings()

'Button1のClickイベントハンドラ
Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) _
        Handles Button1.Click
    '設定"Message"を表示
    TextBox1.Text = CStr(appSettings.Message)
End Sub

'Button2のClickイベントハンドラ
Private Sub Button2_Click(ByVal sender As Object, ByVal e As EventArgs) _
        Handles Button2.Click
    '設定"Message"に値を設定して、保存
    appSettings.Message = TextBox1.Text
    appSettings.Save()
End Sub
C#
コードを隠すコードを選択
//設定
TestSettings appSettings = new TestSettings();

//Button1のClickイベントハンドラ
private void Button1_Click(object sender, EventArgs e)
{
    //設定"Message"を表示
    TextBox1.Text = (string)appSettings.Message;
}

//Button2のClickイベントハンドラ
private void Button2_Click(object sender, EventArgs e)
{
    //設定"Message"に値を設定して、保存
    appSettings.Message = TextBox1.Text;
    appSettings.Save();
}

このようにして設定を保存すると、その内容はこちらで紹介したように、user.configファイルに保存されます。具体的には、次のようになります。

アプリケーションスコープの設定を作成する

アプリケーションスコープの設定の場合は、プロパティにApplicationScopedSettingAttribute属性を適用します。ただしこの場合は、後述するDefaultSettingValueAttribute属性を適用するか、アプリケーション構成ファイルで値を指定しなければなりません。

なおアプリケーション構成ファイルに既定値を記述する方法に関しては、MSDNの「アプリケーション設定のスキーマ」をご覧ください。(または、「Visual Studioでアプリケーションの設定を保存する」の方法で作成されるアプリケーション構成ファイルの中身を見れば、大体のことは分かるでしょう。)

設定プロパティには、UserScopedSettingAttributeかApplicationScopedSettingAttributeのどちらかが適用されている必要があります。

VB.NET
コードを隠すコードを選択
<ApplicationScopedSetting(), _
DefaultSettingValue("0")> _
Public Property Number() As Integer
    Get
        Return CInt(Me("Number"))
    End Get
    Set(ByVal value As Integer)
        Me("Number") = value
    End Set
End Property
C#
コードを隠すコードを選択
[ApplicationScopedSetting()]
[DefaultSettingValue("0")]
public int Number
{
    get
    {
        return (int)this["Number"];
    }
    set
    {
        this["Number"] = value;
    }
}

既定値を指定する

設定の既定値を指定するには、DefaultSettingValueAttribute属性を適用します。DefaultSettingValueAttributeに指定できる文字列は、XMLシリアル化されたものではいけません。

また、アプリケーション構成ファイルに既定値を記述しておくこともできます。

設定グループの名前を変更する

設定はグループ単位で管理されます。グループが違えば同じ名前の設定でも別の設定として保存されますが、グループが同じだと同じ名前の設定はまったく同じものとして扱われます。

この設定グループは、先に示したuser.configファイルでいえば、「TestSettings」という名前になっている部分です。

この設定グループの名前を変更するには、設定クラスにSettingsGroupNameAttribute属性を適用します。設定プロパティにSettingsGroupNameAttribute属性を適用することはできません。なおデフォルトでは、設定クラス名がグループ名になります。

例えば、次のような設定クラスを作成したとします。

VB.NET
コードを隠すコードを選択
Imports System.Configuration

<SettingsGroupName("設定のテスト")> _
Public Class TestSettings
    Inherits ApplicationSettingsBase

    <UserScopedSetting()> _
    Public Property Message() As String
        Get
            Return CStr(Me("Message"))
        End Get
        Set(ByVal value As String)
            Me("Message") = value
        End Set
    End Property
End Class
C#
コードを隠すコードを選択
using System.Configuration;

[SettingsGroupName("設定のテスト")]
public class TestSettings : ApplicationSettingsBase
{
    [UserScopedSetting()]
    public string Message
    {
        get
        {
            return (string)this["Message"];
        }
        set
        {
            this["Message"] = value;
        }
    }
}

この設定を保存すると、user.configファイルは次のようになります。

設定グループ名を、別の設定クラスが使用しているグループ名と同じにすることもできます。この場合、名前が同じ設定は、同じ設定として保存されます。

設定キーを設定する

同じ設定クラスを使用すると、同じ設定グループ名となりますので、同じ設定クラスのインスタンスを複数作成して設定を保存すると、それぞれの設定の区別が付かなくなってしまいます。それでは困るような場合は、それぞれのインスタンスのApplicationSettingsBase.SettingsKeyプロパティに別々の名前(「設定キー」と呼ばれる)を指定します。

次の例では、先ほど作成したTestSettings設定クラスのインスタンスを2つ作成して、別々の設定キーを指定してから、保存しています。

VB.NET
コードを隠すコードを選択
'設定1
Dim set1 As New TestSettings()
'設定キーを指定する
set1.SettingsKey = "設定1"
'設定"Message"に値を設定して、保存
set1.Message = "こんにちは。"
set1.Save()

'設定2
Dim set2 As New TestSettings()
'設定キーを指定する
set2.SettingsKey = "設定2"
'設定"Message"に値を設定して、保存
set2.Message = "こんばんは。"
set2.Save()
C#
コードを隠すコードを選択
//設定1
TestSettings set1 = new TestSettings();
//設定キーを指定する
set1.SettingsKey = "設定1";
//設定"Message"に値を設定して、保存
set1.Message = "こんにちは。";
set1.Save();

//設定2
TestSettings set2 = new TestSettings();
//設定キーを指定する
set2.SettingsKey = "設定2";
//設定"Message"に値を設定して、保存
set2.Message = "こんばんは。";
set2.Save();

このようにして保存されたuser.configファイルの中身は次のようになります。

設定の説明を記述する

設定に説明をつけるには、設定プロパティにSettingsDescriptionAttribute属性を適用します。

また、設定グループに説明をつけるには、設定クラスにSettingsGroupDescriptionAttribute属性を適用します。

シリアル化する方法を変更する

設定を保存するときにどのようにシリアル化するかをSettingsSerializeAsAttribute属性で指定することができます。指定できる種類は、Binary(バイナリ)、String(プレーンテキスト)、Xml(XMLのシリアル化)、ProviderSpecific(カスタムのシリアル化)です。

SettingsSerializeAsAttributeで指定されたものはあくまで要求で、実際にそのようにシリアル化される保障はありません。

これらの違いを具体的に見てみましょう。まずは次のような設定クラスを作成します。

VB.NET
コードを隠すコードを選択
Imports System.Drawing
Imports System.Configuration

Public Class TestSettings
    Inherits ApplicationSettingsBase

    <UserScopedSetting(), _
    SettingsSerializeAs(SettingsSerializeAs.String)> _
    Public Property LocationString() As Point
        Get
            Return CType(Me("LocationString"), Point)
        End Get
        Set(ByVal value As Point)
            Me("LocationString") = value
        End Set
    End Property

    <UserScopedSetting(), _
    SettingsSerializeAs(SettingsSerializeAs.Xml)> _
    Public Property LocationXml() As Point
        Get
            Return CType(Me("LocationXml"), Point)
        End Get
        Set(ByVal value As Point)
            Me("LocationXml") = value
        End Set
    End Property

    <UserScopedSetting(), _
    SettingsSerializeAs(SettingsSerializeAs.Binary)> _
    Public Property LocationBinary() As Point
        Get
            Return CType(Me("LocationBinary"), Point)
        End Get
        Set(ByVal value As Point)
            Me("LocationBinary") = value
        End Set
    End Property

    <UserScopedSetting(), _
    SettingsSerializeAs(SettingsSerializeAs.ProviderSpecific)> _
    Public Property LocationProviderSpecific() As Point
        Get
            Return CType(Me("LocationProviderSpecific"), Point)
        End Get
        Set(ByVal value As Point)
            Me("LocationProviderSpecific") = value
        End Set
    End Property
End Class
C#
コードを隠すコードを選択
using System.Drawing;
using System.Configuration;

public class TestSettings : ApplicationSettingsBase
{
    [UserScopedSetting()]
    [SettingsSerializeAs(SettingsSerializeAs.String)]
    public Point LocationString
    {
        get
        {
            return (Point)this["LocationString"];
        }
        set
        {
            this["LocationString"] = value;
        }
    }

    [UserScopedSetting()]
    [SettingsSerializeAs(SettingsSerializeAs.Xml)]
    public Point LocationXml
    {
        get
        {
            return (Point)this["LocationXml"];
        }
        set
        {
            this["LocationXml"] = value;
        }
    }

    [UserScopedSetting()]
    [SettingsSerializeAs(SettingsSerializeAs.Binary)]
    public Point LocationBinary
    {
        get
        {
            return (Point)this["LocationBinary"];
        }
        set
        {
            this["LocationBinary"] = value;
        }
    }

    [UserScopedSetting()]
    [SettingsSerializeAs(SettingsSerializeAs.ProviderSpecific)]
    public Point LocationProviderSpecific
    {
        get
        {
            return (Point)this["LocationProviderSpecific"];
        }
        set
        {
            this["LocationProviderSpecific"] = value;
        }
    }
}

この設定を、Saveメソッドで保存すると、次のような内容のファイルが作成されます。

Upgradeメソッドが呼び出されても前のバージョンの値を引き継がないようにする

こちらで紹介したように、Upgradeメソッドを使って前のバージョンの設定を引き継ぐことができます。Upgradeメソッドを呼び出しても前の設定を使わずに無視するには、設定プロパティにNoSettingsVersionUpgradeAttribute属性を適用します。

注意:この記事では、基本的な事柄の説明が省略されているかもしれません。初心者の方は、特に以下の点にご注意ください。

  • イベントハンドラの意味が分からない、C#のコードをそのまま書いても動かないという方は、こちらをご覧ください。
  • .NET Tipsをご利用いただく際は、注意事項をお守りください。