ComplexConverter: alles in einen String und zurück

    • VB.NET
    • .NET (FX) 1.0–2.0

    Es gibt 26 Antworten in diesem Thema. Der letzte Beitrag () ist von RodFromGermany.

      Ich hab mir gerade dein Beispiel Projekt angeschaut, in diesem wird ja erklärt wie man die ListView-Spaltenbreite konvertieren kann. Anhand dieses Beispiels habe ich versucht die ColumnHeader zu konvertieren.

      VB.NET-Quellcode

      1. For Each Col As ColumnHeader In Me.ListView1.Columns
      2. e.ConvertValue(Col.Text)
      3. e.ConvertValue(Col.Width)
      4. Next


      Leider setzen sich die Values nur zurück und die kein Columnheader wird geladen.

      Admin-Anmerkung: Lösung hier: ListView - Speichern und Laden der ColumnHeader und der Items/Subitems in einer(/mehrere?) .txt-Datei(en)

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Marcus Gräfe“ ()

      Finde ich soweit echt praktisch, hab aber ein paar Fragen:
      Wie läuft das mit den Listen?
      Was passiert bei ConvertList(Of T) genau (also was wird im Hintergrund gemacht)?
      Wie wird die Anzahl an Elementen in einer Liste wiederhergestellt? Beispiel dazu:

      VB.NET-Quellcode

      1. Public Shared Rnd As New Random 'Global verfügbar
      2. Public Class FunkyData
      3. Public Property Value As Integer '+ Backing Field
      4. Private Sub New(NewValue As Integer) 'Kann von außen nicht instanziert werden, und schon garnicht mit dem Standardkonstruktor.
      5. Value = NewValue
      6. End Sub
      7. Public Shared Function CreateNew() As FunkyData
      8. Return New FunkyData(Rnd.Next(0, 100))
      9. End Function
      10. End Class
      11. Dim WithEvents Converter As New ComplexConverter
      12. Dim Items As List(Of FunkyData)
      13. Sub Foo()
      14. Items = New List(Of FunkyData)
      15. For i = 1 To Rnd.Next(5, 11)
      16. Items.Add(FunkyData.CreateNew())
      17. Next
      18. Dim Saved = Converter.CreateDataString()
      19. Items = Nothing 'Tun wir mal so, als würden wir den alten Zustand vergessen.
      20. Converter.ApplyDataString(Saved)
      21. End Sub
      22. Sub ConverterDingsda(sender, e) Handles ...
      23. e.ConvertList(Of FunkyData)(Items) 'Was macht das?
      24. For Each i In Items 'Würde beim zweiten Aufruf wohl crashen. Wie wird das gehandhabt?
      25. e.ConvertValue(i.Value)
      26. Next
      27. End Sub


      Bezüglich Vorteile:
      Ich hab das Teil noch nicht heruntergeladen und deshalb auch noch nicht gesehen, wie so ein Daten-String aussieht, aber ich vermute mal, dass er einigermaßen lesbar ist (Vielleicht kann ErfinderDesRades ein Beispiel posten?). Das ist meiner Meinung nach eine wertvolle Eigenschaft. Wenn man Bytes möchte, kann man immer noch über Encoding.GetBytes gehen.
      Eventuell würde es Sinn machen, bei großen Datenstrukturen mit Streams zu arbeiten. Das wäre ein Punkt für Serialisierung. Wie relevant das tatsächlich ist, kann ich aber nicht abschätzen.
      "Luckily luh... luckily it wasn't poi-"
      -- Brady in Wonderland, 23. Februar 2015, 1:56
      Desktop Pinner | ApplicationSettings | OnUtils

      ComplexConverter-Update + noch ein Sample

      (@Niko: Ich hab nicht geantwortet, weil a) ist die Serialisierungs-Diskussion Komplett-Unfug, das mag ich nicht nochmal durchkauen b) Du stellst eine Frage zur inneren Funktionalität, ohne ühaupt einen Blick in den Code geworfen zu haben - hast ihn noch nichtmal downgeloadet)

      Update:
      • Ich hab den Retry noch verbessern können - vb verhält sich etwas komisch bei ByRef übergebenen Properties (naja - verstehe wer will, ist jetzt jdfs. noch stabiler)
      • ApplyDatastring gibt jetzt einen Boolean zurück, dass man extra nochmal reagieren kann, wenn eine Zustands-Wiederherstellung nicht möglich war (etwa weil noch kein Zustand gespeichert wurde).
      • Das EventArgs hat nun eine Methode ConvertExplicitTyped(Of T). Damit kann man nun Daten speichern, die nur untypisiert als Objekt vorliegen, deren Datentyp man aber kennt und angeben kann.
      Das Sample speichert wieder alles mögliche, diesmal (meist) von einem DatagridView:

      VB.NET-Quellcode

      1. Public Class frmDgv
      2. Private WithEvents _Memory As New ComplexConverter
      3. Public Sub New()
      4. InitializeComponent()
      5. Dgv.ColumnCount = 8
      6. If Not _Memory.ApplyDataString(My.Settings.DgvMemory) Then
      7. Dgv.RowCount = 6
      8. For x = 0 To Dgv.ColumnCount - 1
      9. Dgv.Columns(x).HeaderText = x.ToString
      10. For y = 0 To Dgv.RowCount - 2
      11. Dgv(x, y).Value = (y + x * 10).ToString("00")
      12. Next
      13. Next
      14. End If
      15. End Sub
      16. Private Sub _Memory_Convert(sender As Object, e As ComplexConverter.EventArg) Handles _Memory.Convert
      17. e.ConvertValue(Me.Bounds)
      18. For Each col As DataGridViewColumn In Dgv.Columns
      19. e.ConvertValue(col.HeaderText)
      20. e.ConvertValue(col.DisplayIndex)
      21. e.ConvertValue(col.Width)
      22. Next
      23. e.ConvertValue(Dgv.RowCount)
      24. For Each rw As DataGridViewRow In Dgv.Rows
      25. e.ConvertValue(rw.Height)
      26. Next
      27. For x = 0 To Dgv.ColumnCount - 1
      28. For y = 0 To Dgv.RowCount - 2
      29. e.ConvertExplicitTyped(Of String)(Dgv(x, y).Value)
      30. Next
      31. Next
      32. End Sub
      33. Private Sub frmDgv_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
      34. My.Settings.DgvMemory = _Memory.CreateDataString
      35. End Sub
      36. Private Sub btClearSettings_Click(sender As Object, e As EventArgs) Handles btClearSettings.Click
      37. My.Settings.DgvMemory = Nothing
      38. RemoveHandler Me.FormClosing, AddressOf frmDgv_FormClosing
      39. System.Media.SystemSounds.Asterisk.Play()
      40. End Sub
      41. End Class

      In Sub New werden Daten nur dann generiert, wenn der ComplexConverter keine ranschaffen konnte (zeilen #8 - 16). (Im Grunde eine kleinliche Optimierung: Es macht nämlich auch nichts, wenn man die Daten immer generiert, und CC überschreibt sie dann.)
      Im Convert-Event wie gesagt alles mögliche:
      • #20: Form-Masse und Position
      • #21 - 25: aller Spalten HeaderText, DisplayIndex und Breite - der User kann sie anordnen wie wolle.
      • #26: Anzahl der Zeilen
      • #27-29: alle Zeilen-Höhen
      • #30-34: alle Zellen-Einträge.
        Die Zellen-Einträge sind wie gesagt mit e.ConvertExplicitTyped() zu persistieren, denn DatagridViewCell-Value hat Datentyp Object - da kann CC nicht selbst von ableiten, welcher TypConverter zuständig ist.

      Das mit den Zellen-Daten ist eigentlich sehr schlechter Stil - Daten sollte man mit Databinding, und in einer typisierten Datenhaltung verwalten. Nicht so wie hier aus Dgv-Zellen puhlen, und einheitlich auf String casten.

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

      @ErfinderDesRades
      Ich wollte mich dem Converter mal annehmen, weil ich gerne die vom Benutzer geänderten Spaltenbreiten in meinen DGV's persistieren will, sodass
      die nach Neustart des Programms auch wieder da sind. Mit dem speichern der expanded TreeNodes hört sich auch gut an und wäre einen Versuch wert.

      Allerdings meckert er an 2 Stellen:


      hast du eine Lösung dazu?

      LG ;)
      "Na, wie ist das Wetter bei dir?"
      "Caps Lock."
      "Hä?"
      "Shift ohne Ende!" :thumbsup:
      @tragl Statt ByVal List As IList machst Du ByVal List As IList(Of Integer).
      Da der @ErfinderDesRades wahrscheinlich das VisualBasic-Zeugs aus seinem Projekt entfernt hat, musst Du nun in VB.NET programmieren. :thumbsup:
      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!
      Danke, ich werd's probieren :thumbup:
      Edit geht nicht:
      Bilder
      • Unbenannt.PNG

        2,43 MB, 704×307, 117 mal angesehen
      "Na, wie ist das Wetter bei dir?"
      "Caps Lock."
      "Hä?"
      "Shift ohne Ende!" :thumbsup:

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

      Der @ErfinderDesRades meinte hier Properties eines eigenen Controls in Datei Speichern/Laden
      dass der ComplexConverter unter C# nicht laufen würde.
      Der 2013er zeigt keinen TreeView und keine RTB an.
      So habe ich die VS2005er Solution runtergeladen nach C# konvertiert, hier ist das Ergebnis:
      ComplexConverterDemoCs.zip
      Sorry, ich hatte die Nicht-Startform offen.
      Hier auch die zweite Solution:
      ComplexConverterDemoCs02.zip
      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!

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