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 Class
Sitten 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 Sub
Eli 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 Namespace
Settings.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 Namespace
Tä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.