Moi,
yritän tässä tallentaa asetuksia My.Settings-systeemillä, mutta on pientä ongelmaa.
En saa millään tehtyä asetusta, jonka tyyppi on itse tekemäni luokka, niin että se luokka on määritelty samassa projektissa. Jos se on määritelty toisessa projektissa niin asetuksen tyypin valinta onnistuu (kunhan laittaa referenssin tietysti).
Tässä pieni esimerkki siitä miltä homma näyttää. Sanotaan projekteja vaikkapa PääProjektiksi ja SivuProjektiksi.
SivuProjektissa määritelty luokka:
<Serializable()> Public Class EräsLuokka
Protected nimi As String
Protected ikä As Single
Public Sub New(ByVal nimensä As String, ByVal ikänsä As Single)
nimi = nimensä
ikä = ikänsä
End Sub
Public Overrides Function ToString() As String
Return nimi & ", " & CStr(ikä) & " vuotta"
End Function
End ClassSitten PääProjektissa:
Project -> Properties -> Settings. Tehdään asetus nimeltä OletusHenkilö ja valitaan sen tyypiksi EräsLuokka.
Testataan esim. Form-loadissa:
Dim hlö As New EräsLuokka("Matti", 32.56!)
My.Settings.OletusHenkilö = hlö
Dim hänTakaisin As EräsLuokka = My.Settings.OletusHenkilö
MsgBox(hänTakaisin.ToString)Tulostaa: "Matti, 32,56 vuotta"
Tässäkin on sellainen ongelma että se ei toimi oikeasti. Esim:
Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
My.Settings.OletusHenkilö = New EräsLuokka("Masa", 41.78)
My.Settings.Save()
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim hlö As EräsLuokka = My.Settings.OletusHenkilö
' Tulee Nothing vaikka on kyllä tallennettu!
MsgBox(hlö.ToString) ' tulee virhe
' (tämä täytyy ajaa ensin kertaalleen ilman tuota MsgBox-riviä)
End SubEli kaksi kysymystä:
Miten Serializable saadaan oikeasti toimimaan?
Miten omat tyypit saadaan näkymään saman projektin asetustaulukossa?
No moro!
Et viittis Copy/Pastettaa Projektisi Properties-kansiosta Settings.setting & Setting.Designer.vb filujen sisältöä näkösälle..?
OK, tässä tulee. Jostain syystä tosin en enää edes saanut valittua sitä omaa tyyppiä, kun testailin muita tyyppejä (menee aina vaan hämärämmäksi). Muutin tähän OletusHlö-asetuksen tyypin käsin jotta siitä näkyy se oikea tyyppi. Tämä on tällainen sekava testiprojekti, noilla asetuksilla ei ole mitään oikeaa merkitystä.
Toivottavasti tajusin nyt oikein mitä tiedostoja tarkoitit.
Settings.vb: (Settings.settings -> View code)
Namespace My
'This class allows you to handle specific events on the settings class:
' The SettingChanging event is raised before a setting's value is changed.
' The PropertyChanged event is raised after a setting's value is changed.
' The SettingsLoaded event is raised after the setting values are loaded.
' The SettingsSaving event is raised before the setting values are saved.
Partial Friend NotInheritable Class MySettings
End Class
End NamespaceSettings.Designer.vb:
'------------------------------------------------------------------------------
' <auto-generated>
' This code was generated by a tool.
' Runtime Version:2.0.50727.3053
'
' Changes to this file may cause incorrect behavior and will be lost if
' the code is regenerated.
' </auto-generated>
'------------------------------------------------------------------------------
Option Strict On
Option Explicit On
Namespace My
<Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
Global.System.CodeDom.Compiler.GeneratedCodeAttribute( _ "Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "9.0.0.0"), _
Global.System.ComponentModel.EditorBrowsableAttribute( _ Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
Partial Friend NotInheritable Class MySettings
Inherits Global.System.Configuration.ApplicationSettingsBase
Private Shared defaultInstance As MySettings =
CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings), MySettings)
#Region "My.Settings Auto-Save Functionality"
#If _MyType = "WindowsForms" Then
Private Shared addedHandler As Boolean
Private Shared addedHandlerLockObject As New Object
<Global.System.Diagnostics.DebuggerNonUserCodeAttribute(),
Global.System.ComponentModel.EditorBrowsableAttribute( _ Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
Private Shared Sub AutoSaveSettings(ByVal sender As Global.System.Object, ByVal e As Global.System.EventArgs)
If My.Application.SaveMySettingsOnExit Then
My.Settings.Save()
End If
End Sub
#End If
#End Region
Public Shared ReadOnly Property [Default]() As MySettings
Get
#If _MyType = "WindowsForms" Then
If Not addedHandler Then
SyncLock addedHandlerLockObject
If Not addedHandler Then
AddHandler My.Application.Shutdown, AddressOf AutoSaveSettings
addedHandler = True
End If
End SyncLock
End If
#End If
Return defaultInstance
End Get
End Property
<Global.System.Configuration.UserScopedSettingAttribute(), _
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.Configuration.DefaultSettingValueAttribute("00:00:00")> _
Public Property Kello() As Global.System.TimeSpan
Get
Return CType(Me("Kello"), Global.System.TimeSpan)
End Get
Set(ByVal value As Global.System.TimeSpan)
Me("Kello") = value
End Set
End Property
<Global.System.Configuration.UserScopedSettingAttribute(), _
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.Configuration.DefaultSettingValueAttribute("0")> _
Public Property Lintuja() As Long
Get
Return CType(Me("Lintuja"), Long)
End Get
Set(ByVal value As Long)
Me("Lintuja") = value
End Set
End Property
<Global.System.Configuration.UserScopedSettingAttribute(), _
Global.System.Diagnostics.DebuggerNonUserCodeAttribute()> _
Public Property OletusFontti() As Global.System.Drawing.Font
Get
Return CType(Me("OletusFontti"), Global.System.Drawing.Font)
End Get
Set(ByVal value As Global.System.Drawing.Font)
Me("OletusFontti") = value
End Set
End Property
<Global.System.Configuration.UserScopedSettingAttribute(), _
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.Configuration.DefaultSettingValueAttribute("")> _
Public Property OletusHlö() As Global.Laskujuttuja.EräsLuokka
Get
Return CType(Me("OletusHlö"), Global.Laskujuttuja.EräsLuokka)
End Get
Set(ByVal value As Global.Laskujuttuja.EräsLuokka)
Me("OletusHlö") = value
End Set
End Property
End Class
End Namespace
Namespace My
<Global.Microsoft.VisualBasic.HideModuleNameAttribute(), _
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute()> _
Friend Module MySettingsProperty
<Global.System.ComponentModel.Design.HelpKeywordAttribute("My.Settings")> _
Friend ReadOnly Property Settings() As Global.Testejä.My.MySettings
Get
Return Global.Testejä.My.MySettings.Default
End Get
End Property
End Module
End NamespaceTässä vielä Settings.settings -tiedoston varsinainen sisältö (avasin Notepadilla), kun en eilen tajunnut tätä kaivaa esiin. Tässä on OletusHlö-asetuksen tyyppi väärin mutta ei haitanne.
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="My" GeneratedClassName="MySettings" UseMySettingsClassName="true">
<Profiles />
<Settings>
<Setting Name="Kello" Type="System.TimeSpan" Scope="User">
<Value Profile="(Default)">00:00:00</Value>
</Setting>
<Setting Name="Lintuja" Type="System.Int64" Scope="User">
<Value Profile="(Default)">0</Value>
</Setting>
<Setting Name="OletusFontti" Type="System.Drawing.Font" Scope="User">
<Value Profile="(Default)" />
</Setting>
<Setting Name="OletusHlö" Type="System.String" Scope="User">
<Value Profile="(Default)" />
</Setting>
</Settings>
</SettingsFile>Unohdin mainita että käytössä on Express Edition. Onko merkitystä tässä asetusten käyttämisessä?
Edit: Laitan tähän vielä user.config-tiedoston johon ne asetukset tallentuvat. Huomasin että yleensä siellä näkyy olevan
serializeAs="String"
ja että jos asetuksen tyypiksi onnistuu valitsemaan oman tyypin (laitoin nyt Form1 koska muuta omaa tyyppiä en onnistunut valitsemaan), niin tuleekin
serializeAs="Xml"
user.config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<userSettings>
<Testejä.My.MySettings>
<setting name="Kello" serializeAs="String">
<value>15:47:58</value>
</setting>
<setting name="Lintuja" serializeAs="String">
<value>500</value>
</setting>
<setting name="OletusHlö" serializeAs="Xml">
<value />
</setting>
<setting name="OletusFontti" serializeAs="String">
<value>Microsoft Sans Serif, 8.25pt</value>
</setting>
</Testejä.My.MySettings>
</userSettings>
</configuration>Edit2: Juuri tuolta se user.config-tiedosto näytti OletusHlö-kohdan osalta, kun olin suorittanut nämä rivit:
My.Settings.OletusHlö = New EräsLuokka("Masa", 41.78)
My.Settings.Save()Eli ei sinne tallentunut yhtään mitään. Sen sijaan kaikki valmiit tyypit tallentuu ilman mitään ongelmia kuten näkyykin.
Pitkällisen "kokeile kaikkea mahdollista" -tyyppisen testailun tuloksena sain tämän viimein toimimaan.
Näyttää siltä että nämä ominaisuudet vaaditaan tallennuskelpoiselta luokalta:
* Public Sub New() ilman argumentteja (ei toki haittaa jos muitakin on)
* Joko julkiset kentät tai julkiset Read-And-Write-ominaisuudet!
Sen sijaan sillä, laittaako sen <Serializable()> siihen eteen vai ei, ei näytä olevan mitään vaikutusta.
Ja sitten se näkyvyysongelma: Kyllä saman projektin tyypit saa valittua, mutta se täytyy kirjoittaa käsin ja vielä namespacen kanssa, esim. Testiprojekti.EräsLuokka. (Jos haluaa isot kirjaimet niin ne täytyy itse laittaa.) Luokka täytyy olla määritelty Public, Friend ei näytä riittävän.
Toimiikohan tämä homma siistimmin Professional-versiossa?
Aihe on jo aika vanha, joten et voi enää vastata siihen.