注意: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属性を適用します。具体的には、次のようなコードになります。
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
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"に格納してから保存しています。
'設定 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
//設定 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ファイルに保存されます。具体的には、次のようになります。
<?xml version="1.0" encoding="utf-8"?> <configuration> <configSections> <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" > <section name="TestSettings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" /> </sectionGroup> </configSections> <userSettings> <TestSettings> <setting name="Message" serializeAs="String"> <value>こんにちは。</value> </setting> </TestSettings> </userSettings> </configuration>
アプリケーションスコープの設定の場合は、プロパティにApplicationScopedSettingAttribute属性を適用します。ただしこの場合は、後述するDefaultSettingValueAttribute属性を適用するか、アプリケーション構成ファイルで値を指定しなければなりません。
なおアプリケーション構成ファイルに既定値を記述する方法に関しては、MSDNの「アプリケーション設定のスキーマ」をご覧ください。(または、「Visual Studioでアプリケーションの設定を保存する」の方法で作成されるアプリケーション構成ファイルの中身を見れば、大体のことは分かるでしょう。)
設定プロパティには、UserScopedSettingAttributeかApplicationScopedSettingAttributeのどちらかが適用されている必要があります。
<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
[ApplicationScopedSetting()] [DefaultSettingValue("0")] public int Number { get { return (int)this["Number"]; } set { this["Number"] = value; } }
設定の既定値を指定するには、DefaultSettingValueAttribute属性を適用します。DefaultSettingValueAttributeに指定できる文字列は、XMLシリアル化されたものではいけません。
また、アプリケーション構成ファイルに既定値を記述しておくこともできます。
設定はグループ単位で管理されます。グループが違えば同じ名前の設定でも別の設定として保存されますが、グループが同じだと同じ名前の設定はまったく同じものとして扱われます。
この設定グループは、先に示したuser.configファイルでいえば、「TestSettings」という名前になっている部分です。
この設定グループの名前を変更するには、設定クラスにSettingsGroupNameAttribute属性を適用します。設定プロパティにSettingsGroupNameAttribute属性を適用することはできません。なおデフォルトでは、設定クラス名がグループ名になります。
例えば、次のような設定クラスを作成したとします。
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
using System.Configuration; [SettingsGroupName("設定のテスト")] public class TestSettings : ApplicationSettingsBase { [UserScopedSetting()] public string Message { get { return (string)this["Message"]; } set { this["Message"] = value; } } }
この設定を保存すると、user.configファイルは次のようになります。
<?xml version="1.0" encoding="utf-8"?> <configuration> <configSections> <sectionGroup name="userSettings"> <section name="設定のテスト" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" /> </sectionGroup> </configSections> <userSettings> <設定のテスト> <setting name="Message" serializeAs="String"> <value>こんにちは。</value> </setting> </設定のテスト> </userSettings> </configuration>
設定グループ名を、別の設定クラスが使用しているグループ名と同じにすることもできます。この場合、名前が同じ設定は、同じ設定として保存されます。
同じ設定クラスを使用すると、同じ設定グループ名となりますので、同じ設定クラスのインスタンスを複数作成して設定を保存すると、それぞれの設定の区別が付かなくなってしまいます。それでは困るような場合は、それぞれのインスタンスのApplicationSettingsBase.SettingsKeyプロパティに別々の名前(「設定キー」と呼ばれる)を指定します。
次の例では、先ほど作成したTestSettings設定クラスのインスタンスを2つ作成して、別々の設定キーを指定してから、保存しています。
'設定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()
//設定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ファイルの中身は次のようになります。
<?xml version="1.0" encoding="utf-8"?> <configuration> <configSections> <sectionGroup name="userSettings"> <section name="TestSettings.設定2" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" /> <section name="TestSettings.設定1" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" /> </sectionGroup> </configSections> <userSettings> <TestSettings.設定2> <setting name="Message" serializeAs="String"> <value>こんばんは。</value> </setting> </TestSettings.設定2> <TestSettings.設定1> <setting name="Message" serializeAs="String"> <value>こんにちは。</value> </setting> </TestSettings.設定1> </userSettings> </configuration>
設定に説明をつけるには、設定プロパティにSettingsDescriptionAttribute属性を適用します。
また、設定グループに説明をつけるには、設定クラスにSettingsGroupDescriptionAttribute属性を適用します。
設定を保存するときにどのようにシリアル化するかをSettingsSerializeAsAttribute属性で指定することができます。指定できる種類は、Binary(バイナリ)、String(プレーンテキスト)、Xml(XMLのシリアル化)、ProviderSpecific(カスタムのシリアル化)です。
SettingsSerializeAsAttributeで指定されたものはあくまで要求で、実際にそのようにシリアル化される保障はありません。
これらの違いを具体的に見てみましょう。まずは次のような設定クラスを作成します。
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
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メソッドで保存すると、次のような内容のファイルが作成されます。
<?xml version="1.0" encoding="utf-8"?> <configuration> <configSections> <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" > <section name="TestSettings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" /> </sectionGroup> </configSections> <userSettings> <TestSettings> <setting name="LocationProviderSpecific" serializeAs="ProviderSpecific"> <value> <Point xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <X>0</X> <Y>0</Y> </Point> </value> </setting> <setting name="LocationString" serializeAs="String"> <value>0, 0</value> </setting> <setting name="LocationBinary" serializeAs="Binary"> <value>AAEAAAD/////AQAAAAAAAAAMAgAAAFFTeXN0ZW0uRHJhd2luZywgVmVyc2lvbj0yLjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAABRTeXN0ZW0uRHJhd2luZy5Qb2ludAIAAAABeAF5AAAICAIAAAAAAAAAAAAAAAs=</value> </setting> <setting name="LocationXml" serializeAs="Xml"> <value> <Point xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <X>0</X> <Y>0</Y> </Point> </value> </setting> </TestSettings> </userSettings> </configuration>
こちらで紹介したように、Upgradeメソッドを使って前のバージョンの設定を引き継ぐことができます。Upgradeメソッドを呼び出しても前の設定を使わずに無視するには、設定プロパティにNoSettingsVersionUpgradeAttribute属性を適用します。