Klassen in My.Settings

  • VB.NET

Es gibt 20 Antworten in diesem Thema. Der letzte Beitrag () ist von DragsTrail.

    Klassen in My.Settings

    Hallo,

    Ich habe ein kleines kurioses Problem. In My.Settings habe ich mehrere Klassen implementiert. Läuft soweit problemlos. Die Klassen habe ich als separates Projekt geschrieben und die DLL´s in das Hauptprojekt unter Verweise eingefügt.

    Es gibt jedoch eine Klasse die jedes mal beim Programmstart aus dem VS 2019 sich einfach resettet. :cursing: Komm einfach nicht drauf warum. UND NUR DIESE KLASSE!!

    Die Klasse ist wie folgt aufgebaut:

    (Empfehlung von hier)
    Class BaseClass
    End Class
    Class Klasse1
    Inherits BaseClass
    End Class
    Class Klasse2
    Inherits BaseClass
    End Class

    Während das Programm läuft kann man mit der Klasse alles machen. Sobald ich das Prog beende und aus dem VS neu starte wird NUR DIESE Klasse resettet.

    An was kann das Liegen?

    Beste grüße

    Verlinkungen angepasst ~VaporiZed

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „VaporiZed“ ()

    DragsTrail schrieb:

    An was kann das Liegen?
    Wahrscheinlich an Deinem Code.
    Poste mal den kompletten Code (bereinigt, gezippt).
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @DragsTrail Es sieht so aus, als hätte die DLL separate Settings. Diese werden jedoch vom Anwendungsframework nicht automatisch unterstützt.
    Ich empfehle Dir, Settings lediglich im WinForm-Hauptprogramm zu halten und dann ggf. die Werte in die DLL hineinzureichen
    oder
    Du implementierst das Settings-Handling selbst.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Wenn ich die ClassLibrary1 in WindowsApp1 als Klasse und nicht als DLL einfüge, kann ich Sie in my.Settings nicht auswählen.

    Wie Implementiert man das Settings-Handling? Hast vielleicht ein Code-Beispiel?

    HAB GERADE FOLLGENDES RAUSGEFUNDEN:

    Wenn ich in my.setting als TEST das Alter oder Augenfarbe ( Siehe PIC1 ) setze, dann bleibt der Wert!

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „DragsTrail“ ()

    @DragsTrail Pack mal beide Projekte in eine gemeinsame Projektmappe und füge die DLL als Projekt, nicht aber als DLL, dem HAuptprogramm als Verweis hinzu.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Jo - wurde ja glaub schon gesagt: Eine Anwendung kann nur ein Settings haben - und zwar die des Startprojekts.
    Hängt damit zusammen, dass Settings in .config-Dateien gespeichert werden.
    Und ein Grundkonzept der Configuration-Technologie ist: Es wird die .config-Datei ausgelesen und verarbeitet, die mit der Eintritts-Assembly verknüpft ist (also die denselben Namen hat wie die Eintritts-Assembly).
    Andere .configs mögen herumfliegen - im selben bin-, oder Appdata-Ordner, mit anderen Assemblies verknüpft - die werden ignoriert.
    @ErfinderDesRades

    Also jetzt noch mal, das ich das jetzt mal gesagt habe:

    Ich habe das Projekt ClassLib1

    Wenn ich dieses aufbaue wie folgt:

    Public Class PROFIL1
    End Class

    Public Class PROFIL2
    End Class

    und das in das Projekt WinApp1 in My.Settings einbaue, werden diese Klassen NICHT und NIE Resettet.

    ABER Wenn ich ClassLib1 so aufbaue:

    Public PROFIL
    End Class

    Public PROFIL_Funktion1
    Inherites PROFIL
    End Class

    WIRD DIESE KLASSE IMMER RESETTET.


    Dabei speilt es keine Rolle ob man nur die DLL im Verweis einbindet oder ob man das ganze Projekt einbindet und den Verweis aus dem Projekt holt, wie du in deinem Video gezeigt hast.
    Vermutlich verstehe ich nicht recht - auch weil deine Beschreibung schlecht lesbar und uneindeutig ist. Ich versuch mal zu übersetzen:

    DragsTrail schrieb:

    Ich habe das Projekt ClassLib1 (vermutlich gemeint ist ClassLib1.vbproj)
    Wenn ich dieses aufbaue wie folgt:

    VB.NET-Quellcode

    1. Public Class PROFIL1
    2. End Class
    3. Public Class PROFIL2
    4. End Class
    Dann hast du wohl ein Projekt namens ClassLib1, welches die Klassen PROFIL1 und PROFIL2 enthält.

    DragsTrail schrieb:

    und das in das Projekt WinApp1 in My.Settings einbaue...
    Das verstehe ich nicht: Wie kann man ein Projekt in Settings einbauen???
    Ich kann immer nur von einem Projekt auf andere Projekte verweisen.
    Aber My.Settings ist eine Klasse - wie kann man ein Projekt in eine Klasse einbauen???

    DragsTrail schrieb:

    ..., werden diese Klassen NICHT und NIE Resettet.
    Eine Klasse kann man nicht resetten - was soll das sein: "Klasse resetten".

    Allenfalls Objekte kann man resetten. Also du kannst ein Objekt der StopWatch-Klasse erzeugen, das Objekt kannste dann Starten und resetten. Aber die Klasse Stopwatch zu resetten ergibt überhaupt keinen Sinn.
    Eine Klasse ist der Bauplan eines Objekts. Also du kannst anhand von Konstruktions-Zeichnungen eine Stoppuhr bauen - die kannste dann starten und resetten.
    Aber die Konstruktions-Zeichnungen kannste doch nicht resetten - willste da iwelche Striche und Linien ausradieren, oder was soll damit gemeint sein?

    DragsTrail schrieb:

    ABER Wenn ich ClassLib1 so aufbaue:

    VB.NET-Quellcode

    1. Public PROFIL
    2. End Class
    Das kompiliert nicht.
    Vermutlich hast du ein Schlüsselwort vergessen, vielleicht meinst du aber auch was ganz anderes.



    Aber egal - mein Problem ist,
    1. was du mit resetten meinst, und wie das, wovon du sprichst wohl unresettet aussieht im Gegensatz zu resettet.
    2. Und was du wohl meinst, wenn du sagst, du würdest ein Projekt in iwelche Settings "einbauen".

    Tatsächlich habe ich noch nie überhaupt irgendetwas an den Settings modifiziert oder gar "eingebaut".
    Settings sind eine generierte Klasse, dazu gedacht, dass man zur Programmierzeit in den Projekteigenschaften da Variablen anlegen kann - welche dann zur Laufzeit verwendbar sind.
    Es gibt einige Spezis, die erfolgreich dieses Konzept erweitern, zu iwelchen Zwecken.
    Ich bin bislang gut klargekommen, ohne daran herumzufummeln.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „ErfinderDesRades“ ()

    Hm, ich glaube ein Testprojekt hochzuladen wäre einfacher gewesen. Aber wurscht. Ich hab's ausprobiert. Das Problem ist, dass das Ganze nicht abgespeichert wird. Ich korrigiere: Es wird als Leereintrag gespeichert. Irgendwie werd ich das Gefühl nicht los, dass die Settings nicht für das Abspeichern komplexer Datentypen gedacht sind. Der eine würde in solch einem Fall vielleicht sagen: nimm ein typisiertes DataSet. Der nächste: nimm ein BinarySerializer oder XmlSerializer (was ja im tDS schon quasi mit drinne ist). Ich steh ja inzwischen auf JsonSerializer. Weil der BinarySerializer für jeden Mist ein Attribut verlangt und außerdem immer Objektinstanzen speichert (obwohl ich nur die Inhalte speichern will) und der Framework-XmlSerializer alles auf Public will. Mit dem Newtonsoft-Json-Paket kann ich den für mich als Ballast betrachteten Kram der beiden anderen Serializer umgehen. Aber hey! Ich merk gerade, dass ich schon ganz weit vom Problem entfernt bin und genügend Passagen geschrieben habe, an den andere bestimmt ganz viel einwenden werden. Ach ja: Provokation zum Schluss: Wie wär's mit ner Datenbank?

    ##########

    Ok, in Post#3 wurde ja was hochgeladen. Hab's jetzt gesehen, aber bin nun zu faul es anzuschauen, da ich die Daten aus dem Video schon verarbeitet habe :|
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „VaporiZed“ ()

    @VaporiZed

    Solange das Programm läuft wird alles ohne Probleme in My.Settings gespeichert.

    Die Projekte habe ich oben gepostet. Aber hier noch mal. Probiere es einfach aus. :)

    Datenbank. NEEEEEE. Dann lieber als XML abspeichern.
    Dateien
    • ClassLibrary1.zip

      (38,8 kB, 75 mal heruntergeladen, zuletzt: )
    • WindowsApp1.zip

      (65,49 kB, 72 mal heruntergeladen, zuletzt: )
    Missverständnis. Dass zur Laufzeit in My.Settings.xxx alles drinsteckt, kann ich nachvollziehen und ist ja auch im Video zu sehen. Es wird aber nichts in der entsprechenden Datei user.config gespeichert - außer eben der o.g. Leereintrag. Daher kann aus dieser Datei auch nichts nach Programmneustart geladen werden, daher der Klasseninstanz"reset". Die Instanzdaten sind nach Programmende weg.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Manage application settings (.NET)
    Application settings can be stored as any data type that is serialized to XML or has a TypeConverter that implements ToString/FromString. The most common types are String, Integer, and Boolean, but you can also store values as Color, Object, or as a connection string.


    Wenn du eigene Klassen in den Settings abspeichern möchtestest, dann brauchst du z.B. einen Converter, wenn diese Klasse zu komplex ist und nicht direkt als XML automatisch serialisiert werden kann. Am einfachste wäre jetzt (finde ich) alle Klassen als <Serializable()> markieren und dann einen TypeConverter für PersonenListe erstellen:

    VB.NET-Quellcode

    1. Imports System.ComponentModel
    2. Imports System.Globalization
    3. Imports System.IO
    4. Imports System.Runtime.Serialization.Formatters.Binary
    5. <Serializable()> ' <--------------!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    6. Public Class Person
    7. Implements ICloneable
    8. Public Function Clone() As Object Implements System.ICloneable.Clone
    9. Return MemberwiseClone()
    10. End Function
    11. Public Sub New()
    12. End Sub
    13. End Class
    14. <Serializable()> ' <--------------!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    15. Public Class Augenfarbe
    16. Inherits Person
    17. Public Sub New()
    18. End Sub
    19. Public Sub New(ByVal Augenfarbe As String)
    20. Me.Augenfarbe = Augenfarbe
    21. End Sub
    22. Public Sub Clear()
    23. Me.Augenfarbe = ""
    24. End Sub
    25. Private _Augenfarbe As String
    26. Public Property Augenfarbe As String
    27. Get
    28. Return _Augenfarbe
    29. End Get
    30. Set(ByVal value As String)
    31. _Augenfarbe = value
    32. End Set
    33. End Property
    34. End Class
    35. <Serializable()> ' <--------------!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    36. Public Class Alter
    37. Inherits Person
    38. Public Sub New()
    39. End Sub
    40. Public Sub New(ByVal Alter As Integer)
    41. Me.Alter = Alter
    42. End Sub
    43. Public Sub Clear()
    44. Me.Alter = 0
    45. End Sub
    46. Private _Alter As Integer
    47. Public Property Alter As Integer
    48. Get
    49. Return _Alter
    50. End Get
    51. Set(ByVal value As Integer)
    52. _Alter = value
    53. End Set
    54. End Property
    55. End Class
    56. ' #########################################################################
    57. ' Diese Klasse benötige ich NUR um sie in My.Settings zu implemetieren
    58. ' Also die List(Of List(Of Person)) soll gespeichert werden
    59. ' #########################################################################
    60. <Serializable()>
    61. <TypeConverter(GetType(PersonenListeTypeConverter))> ' <--------------!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    62. Public Class PersonenListe
    63. Public Sub New()
    64. End Sub
    65. Public Sub New(ByVal PersonenListe As List(Of List(Of Person)))
    66. Me.PersonenListe = PersonenListe
    67. End Sub
    68. Public Sub Clear()
    69. Me.PersonenListe = New List(Of List(Of Person))
    70. End Sub
    71. Private _PersonenListe As New List(Of List(Of Person))
    72. Public Property PersonenListe As List(Of List(Of Person))
    73. Get
    74. Return _PersonenListe
    75. End Get
    76. Set(ByVal value As List(Of List(Of Person)))
    77. _PersonenListe = value
    78. End Set
    79. End Property
    80. End Class
    81. ' Der Konverter
    82. <TypeConverter(GetType(PersonenListeTypeConverter))>
    83. Public Class PersonenListeTypeConverter
    84. Inherits TypeConverter
    85. Public Sub New()
    86. End Sub
    87. Public Overrides Function ConvertTo(context As ITypeDescriptorContext, culture As CultureInfo, value As Object, destinationType As Type) As Object
    88. Using mem As New MemoryStream
    89. Dim x As New BinaryFormatter()
    90. x.Serialize(mem, value)
    91. Return Convert.ToBase64String(mem.ToArray())
    92. End Using
    93. End Function
    94. Public Overrides Function CanConvertFrom(context As ITypeDescriptorContext, sourceType As Type) As Boolean
    95. Return sourceType = GetType(String)
    96. End Function
    97. Public Overrides Function ConvertFrom(context As ITypeDescriptorContext, culture As CultureInfo, value As Object) As Object
    98. Using mem As New MemoryStream(Convert.FromBase64String(DirectCast(value, String)))
    99. Dim x As New BinaryFormatter()
    100. Return x.Deserialize(mem)
    101. End Using
    102. End Function
    103. End Class



    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Bluespide“ ()

    Ich hab folgendes Experiment gebastelt:

    VB.NET-Quellcode

    1. Imports ClassLibrary1
    2. Public Class Form1
    3. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    4. If My.Settings.TEST Is Nothing Then
    5. My.Settings.TEST = New PersonenListe()
    6. Dim p As New List(Of Person)
    7. p.Add(New Augenfarbe("Blau"))
    8. 'p.Add(New Alter(20))
    9. Dim ppl As New List(Of List(Of Person))
    10. 'ppl.Add(p)
    11. Dim pl As PersonenListe = New PersonenListe(ppl)
    12. My.Settings.TEST = pl
    13. Else
    14. Dim pl = My.Settings.TEST.PersonenListe
    15. pl.Add(New List(Of Person) From {New Person}) ' das funzt - pl wird von start zu start länger
    16. 'pl.Add(New List(Of Person) From {New Augenfarbe($"Blau{pl.Count}")})' funzt net: eine List(Of Person) mit Augenfarbe drin serialisiert nicht
    17. Dim i = 9 ' hier Haltepunkt
    18. End If
    19. My.Settings.Save()
    20. End
    21. End Sub
    22. End Class
    Also es liegt an der Polymorphie - das können die Settings nicht serialisieren. Könnte man nun probieren, obs an XmlSerialisierung liegt (was die Settings scheints verwenden) - also ob XmlSerialisierung generell eine polymorphe Liste (zB eine List(Of Person), wo nicht eine Person drin ist, sondern eine Augenfarbe) nicht serialisieren kann.
    Vonne Syntax her ist derlei Polymorphie zulässig, weil Augenfarbe erbt ja von Person.
    Aber einer von beiden ist zu doof dafür: entweder die Settings oder die zugrundeliegende XmlSerialisierung.

    Aber letztlich egal - mit dem TypeConverter bist du ja quasi auf Serialisierung per BinaryFormatter umgestiegen - der kann das offsichtlich.

    Im Anhang mein SampleProject
    Dateien