Benutzer mit den meisten Antworten
Applikations-Einstellungen speichern

Frage
-
Hallo zusammen
Ich habe eine Klasse entwickelt, um die Position eines Forms zu speichern und zu laden. Da diese Klasse für mehrere Forms ist, habe ich eine Collection erstellt, die als Elemente die die Position etc. enthält:
Friend Class clsForm Private mintWindowState As FormWindowState = FormWindowState.Normal Private mobjLocation As Point = New Point(0, 0) Private mobjSize As Size = New Size(800, 600) Public Sub New() End Sub Public Sub New(ByVal Location As Point, ByVal Size As Size, ByVal WindowState As FormWindowState) mobjLocation = Location mobjSize = Size mintWindowState = WindowState End Sub Protected Overrides Sub Finalize() mobjLocation = Nothing mobjSize = Nothing MyBase.Finalize() End Sub Public Property Location() As Point Get Return mobjLocation End Get Set(ByVal Value As Point) mobjLocation = Value End Set End Property Public Property Size() As Size Get Return mobjSize End Get Set(ByVal Value As Size) mobjSize = Value End Set End Property Public Property WindowState() As FormWindowState Get Return mintWindowState End Get Set(ByVal Value As FormWindowState) mintWindowState = Value End Set End Property End Class
Nun möchte ich die Collection in den Applikationseinstellungen speichern (mobjCol ist die genannte Collection):
With My.Settings .FormPositions = mobjCol .Save() End With
Dies funktioniert, bis die Applikation geschlossen wird. Danach ist die Setting FormPositions (vom Typ Collection) wieder leer.
Was mach ich da falsch?
Danke für eure Antwort
PS: Das speichern eines String-Wertes funktioniert.
Antworten
-
Hallo,
Private Sub Close(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Try mobjCol.Remove(sender.Name) Catch End Try Try mobjCol.Add(New clsForm(sender.Location, sender.Size, sender.WindowState), sender.Name) With My.Settings .FormPositions = mobjCol .Save() End With Catch ex As Exception RaiseEvent Close_Error(ex.Message) End Try End Sub End Class
das funktioniert so nicht. Eine Collection kann nicht über den SettingsManager serialisiert werden. Zum einen weil die Inhalte untypisiert sind, zum anderen versteht es der SettingsManager nicht eine Key => Value Collection zu serialisieren. Ein typisiertes Dictionary(Of String, clsForm) würde also ebenso wenig funktionieren.
Ein alternativer Ansatz wäre eine eigene Auflistungsklasse, die von List(Of T) erbt. Diese erleichtert das Handling in Verbindung mit dem Settings Designer, zudem ermöglicht sie die Implementierung spezieller Methoden, um eine Key => Value Zuordnung zu simulieren. Die Klassen FormSettings + FormSetting:
Public Class FormSetting Private m_Name As String Private m_WindowState As FormWindowState = FormWindowState.Normal Private m_Location As Point = New Point(0, 0) Private m_Size As Size = New Size(800, 600) Public Sub New() End Sub Public Sub New(ByVal name As String, _ ByVal location As Point, _ ByVal size As Size, _ ByVal windowState As FormWindowState) Me.Name = name Me.Location = location Me.Size = size Me.WindowState = windowState End Sub Public Property Name() As String Get Return m_Name End Get Set(ByVal value As String) m_Name = value End Set End Property Public Property Location() As Point Get Return m_Location End Get Set(ByVal value As Point) m_Location = Value End Set End Property Public Property Size() As Size Get Return m_Size End Get Set(ByVal value As Size) m_Size = Value End Set End Property Public Property WindowState() As FormWindowState Get Return m_WindowState End Get Set(ByVal value As FormWindowState) m_WindowState = value End Set End Property End Class Public Class FormSettings Inherits List(Of FormSetting) Public Overloads Function Contains(ByVal name As String) As Boolean Return Me.Exists(Function(t) (t.Name = name)) End Function Public Overloads ReadOnly Property Item(ByVal name As String) As FormSetting Get Return Me.Find(Function(t) t.Name = name) End Get End Property End Class
Um diese Einstellungen in My.Settings bekannt zu machen, ist ein manueller Eingriff in die Settings Deklaration notwending.
- Dazu musst Du Dir im Projektmappenexplorer zunächst alle Dateien anzeigen lassen
- Öffnest den Zweig "My Project" und
- Klickst dort die Datei "Settings.settings" mit der rechten Maustaste an
- Wählst den Menüpunkt "Öffnen mit"
- Im nachfolgenden Dialog wählst Du "XML Editor" aus
- In der geöffneten Datei suchst Du Deinen Eintrag, der die Einstellungen bisher als Collection speichern sollte
- Änderst bei diesem Eintrag den Wert im Type Attribut in "Namespace.FormSettings"
Namespace ersetzt Du hier natürlich durch den passenden Namespace Bezeichner Deines Projekts. - Änderungen speichern und Projekt neu erstellen lassen.
Anwendung im Formular:
Public Class Form1 Private Sub Form1_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load If My.Settings.Forms Is Nothing Then My.Settings.Forms = New FormSettings End If End Sub Private Sub Button1_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Button1.Click If My.Settings.Forms.Contains("Foo") Then Debug.Print("Using existing setting") My.Settings.Forms.Item("Foo").WindowState = FormWindowState.Maximized Else Debug.Print("Creating new setting") My.Settings.Forms.Add(New FormSetting("Foo", _ New Point(10, 10), _ New Size(700, 400), _ FormWindowState.Normal)) End If My.Settings.Save() End Sub End Class
Thorsten Dörfler
Microsoft MVP Visual Basic
vb-faq.de- Als Antwort markiert eipalittau Mittwoch, 29. September 2010 08:32
-
Hallo,
Kleiner Wehrmutstropfen: Wie kann ich die Klasse clsForm verstecken. (Da nun von clsForm geerbt wird, kann sie nicht mehr Friend sein)
die beiden Klassen FormSettings + FormSetting müssen öffentlich sichtbar sein, sonst funktioniert das Serialisieren nicht. Du kannst höchstens dafür sorgen, dass die beiden Klassen nicht im Objektbrowser bzw. im Codeeditor angezeigt werden, dazu wendest Du das Attribut EditorBrowsable auf die beiden Klassen an:
<System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)> _ Class FormSettings
Allerdings wirkt das für das gesamte Projekt und kann beim Entwickeln eher hinderlich sein.
Thorsten Dörfler
Microsoft MVP Visual Basic
vb-faq.de- Als Antwort markiert eipalittau Mittwoch, 29. September 2010 19:43
Alle Antworten
-
Hallo,
Nun möchte ich die Collection in den Applikationseinstellungen speichern (mobjCol ist die genannte Collection):
With My.Settings .FormPositions = mobjCol .Save() End With
Dies funktioniert, bis die Applikation geschlossen wird. Danach ist die Setting FormPositions (vom Typ Collection) wieder leer.
Was mach ich da falsch?
das ist nicht so leicht zu sagen, da Du leider nicht zeigst, von welchem Typ Dein Setting "FormPositions", sowie Deine Variable "mobjCol" sind. Einen Typ "Collection" gibt es bei der Auswahl der Settings nicht. Oder wie hast Du die Einstellung "FormPositions" erstellt?
Thorsten Dörfler
Microsoft MVP Visual Basic
vb-faq.de -
Hallo,
ich habe Dein doppeltes Posting im allgemeinen Visual Basic Forum gelöscht. Es ist ausreichend, wenn Du Deine Anfrage in einem Forum stellst. Sonst kann es vorkommen, dass zur Lösung des Problems andere Teilnehmer die Information nicht mitbekommen, die im jeweils anderen Thread gegeben wurden. Wenn Du meinst, dass Dein Beitrag bessser im allgemeinen Visual Basic Forum untergebracht wäre, gib mir bitte Bescheid, dann verschiebe ich diesen Thread entsprechend.
Danke für Dein Verständnis!
Thorsten Dörfler
Microsoft MVP Visual Basic
vb-faq.de -
Hier mal der komplette Code:
Die Setting FormPositions ist vom Typ Microsoft.VisualBasic.Collection und als Benutzer (Bereich) deklariert.Public Class Formular Public Event Open_Error(ByVal Message As String) Public Event Close_Error(ByVal Message As String) Private mobjCol As Collection = Nothing Private mobjItem As clsForm = Nothing Public Sub New(ByRef Target As Form) mobjCol = My.Settings.FormPositions If mobjCol Is Nothing Then mobjCol = New Collection Try mobjItem = mobjCol.Item(Target.Name) Catch mobjItem = New clsForm() End Try AddHandler Target.Load, AddressOf Open AddHandler Target.FormClosing, AddressOf Close End Sub Protected Overrides Sub Finalize() mobjCol.Clear() mobjCol = Nothing mobjItem = Nothing MyBase.Finalize() End Sub Private Sub Open(ByVal sender As System.Object, ByVal e As System.EventArgs) sender.Location = mobjItem.Location sender.Size = mobjItem.Size sender.WindowState = mobjItem.WindowState End Sub Private Sub Close(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Try mobjCol.Remove(sender.Name) Catch End Try Try mobjCol.Add(New clsForm(sender.Location, sender.Size, sender.WindowState), sender.Name) With My.Settings .FormPositions = mobjCol .Save() End With Catch ex As Exception RaiseEvent Close_Error(ex.Message) End Try End Sub End Class
-
Hallo,
Private Sub Close(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Try mobjCol.Remove(sender.Name) Catch End Try Try mobjCol.Add(New clsForm(sender.Location, sender.Size, sender.WindowState), sender.Name) With My.Settings .FormPositions = mobjCol .Save() End With Catch ex As Exception RaiseEvent Close_Error(ex.Message) End Try End Sub End Class
das funktioniert so nicht. Eine Collection kann nicht über den SettingsManager serialisiert werden. Zum einen weil die Inhalte untypisiert sind, zum anderen versteht es der SettingsManager nicht eine Key => Value Collection zu serialisieren. Ein typisiertes Dictionary(Of String, clsForm) würde also ebenso wenig funktionieren.
Ein alternativer Ansatz wäre eine eigene Auflistungsklasse, die von List(Of T) erbt. Diese erleichtert das Handling in Verbindung mit dem Settings Designer, zudem ermöglicht sie die Implementierung spezieller Methoden, um eine Key => Value Zuordnung zu simulieren. Die Klassen FormSettings + FormSetting:
Public Class FormSetting Private m_Name As String Private m_WindowState As FormWindowState = FormWindowState.Normal Private m_Location As Point = New Point(0, 0) Private m_Size As Size = New Size(800, 600) Public Sub New() End Sub Public Sub New(ByVal name As String, _ ByVal location As Point, _ ByVal size As Size, _ ByVal windowState As FormWindowState) Me.Name = name Me.Location = location Me.Size = size Me.WindowState = windowState End Sub Public Property Name() As String Get Return m_Name End Get Set(ByVal value As String) m_Name = value End Set End Property Public Property Location() As Point Get Return m_Location End Get Set(ByVal value As Point) m_Location = Value End Set End Property Public Property Size() As Size Get Return m_Size End Get Set(ByVal value As Size) m_Size = Value End Set End Property Public Property WindowState() As FormWindowState Get Return m_WindowState End Get Set(ByVal value As FormWindowState) m_WindowState = value End Set End Property End Class Public Class FormSettings Inherits List(Of FormSetting) Public Overloads Function Contains(ByVal name As String) As Boolean Return Me.Exists(Function(t) (t.Name = name)) End Function Public Overloads ReadOnly Property Item(ByVal name As String) As FormSetting Get Return Me.Find(Function(t) t.Name = name) End Get End Property End Class
Um diese Einstellungen in My.Settings bekannt zu machen, ist ein manueller Eingriff in die Settings Deklaration notwending.
- Dazu musst Du Dir im Projektmappenexplorer zunächst alle Dateien anzeigen lassen
- Öffnest den Zweig "My Project" und
- Klickst dort die Datei "Settings.settings" mit der rechten Maustaste an
- Wählst den Menüpunkt "Öffnen mit"
- Im nachfolgenden Dialog wählst Du "XML Editor" aus
- In der geöffneten Datei suchst Du Deinen Eintrag, der die Einstellungen bisher als Collection speichern sollte
- Änderst bei diesem Eintrag den Wert im Type Attribut in "Namespace.FormSettings"
Namespace ersetzt Du hier natürlich durch den passenden Namespace Bezeichner Deines Projekts. - Änderungen speichern und Projekt neu erstellen lassen.
Anwendung im Formular:
Public Class Form1 Private Sub Form1_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load If My.Settings.Forms Is Nothing Then My.Settings.Forms = New FormSettings End If End Sub Private Sub Button1_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Button1.Click If My.Settings.Forms.Contains("Foo") Then Debug.Print("Using existing setting") My.Settings.Forms.Item("Foo").WindowState = FormWindowState.Maximized Else Debug.Print("Creating new setting") My.Settings.Forms.Add(New FormSetting("Foo", _ New Point(10, 10), _ New Size(700, 400), _ FormWindowState.Normal)) End If My.Settings.Save() End Sub End Class
Thorsten Dörfler
Microsoft MVP Visual Basic
vb-faq.de- Als Antwort markiert eipalittau Mittwoch, 29. September 2010 08:32
-
Danke Thorsten. Es funktioniert. Schnelle und kompetente Antwort! Ich habe das ganze noch ein bischen umgeschrieben. Es fehlt jedoch noch das Error-Handlung...
Kleiner Wehrmutstropfen: Wie kann ich die Klasse clsForm verstecken. (Da nun von clsForm geerbt wird, kann sie nicht mehr Friend sein)Public Class Formular Inherits List(Of clsForm) Private mobjItem As clsForm = Nothing Private Sub New() End Sub Public Sub New(ByRef Target As Form) If My.Settings.FormPositions Is Nothing Then My.Settings.FormPositions = New Formular() If My.Settings.FormPositions.Contains(Target.Name) Then mobjItem = My.Settings.FormPositions.Item(Target.Name) Else mobjItem = New clsForm() End If AddHandler Target.Load, AddressOf Open AddHandler Target.FormClosing, AddressOf Close End Sub Protected Overrides Sub Finalize() mobjItem = Nothing MyBase.Finalize() End Sub Private Overloads Function Contains(ByVal Name As String) As Boolean Return Me.Exists(Function(t) (t.Name = Name)) End Function Private Overloads ReadOnly Property Item(ByVal name As String) As clsForm Get Return Me.Find(Function(t) t.Name = name) End Get End Property Private Sub Open(ByVal sender As System.Object, ByVal e As System.EventArgs) 'Prüfen ob Size grösser als Bildschirm und Location in Bildschirm ist. sender.Location = mobjItem.Location sender.Size = mobjItem.Size sender.WindowState = mobjItem.WindowState End Sub Private Sub Close(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Dim strName As String = sender.Name On Error Resume Next With My.Settings If .FormPositions.Contains(strName) Then .FormPositions.Remove(mobjItem) .FormPositions.Add(New clsForm(sender.Name, sender.Location, sender.Size, sender.WindowState)) .Save() End With End Sub End Class
-
Hallo,
Kleiner Wehrmutstropfen: Wie kann ich die Klasse clsForm verstecken. (Da nun von clsForm geerbt wird, kann sie nicht mehr Friend sein)
die beiden Klassen FormSettings + FormSetting müssen öffentlich sichtbar sein, sonst funktioniert das Serialisieren nicht. Du kannst höchstens dafür sorgen, dass die beiden Klassen nicht im Objektbrowser bzw. im Codeeditor angezeigt werden, dazu wendest Du das Attribut EditorBrowsable auf die beiden Klassen an:
<System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)> _ Class FormSettings
Allerdings wirkt das für das gesamte Projekt und kann beim Entwickeln eher hinderlich sein.
Thorsten Dörfler
Microsoft MVP Visual Basic
vb-faq.de- Als Antwort markiert eipalittau Mittwoch, 29. September 2010 19:43