WinForms-DGV: Rohwert in der Datenquelle, Anzeige aber formatiert (mit Anhang) - Optimierungsmöglichkeit gesucht [gelöst]

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 14 Antworten in diesem Thema. Der letzte Beitrag () ist von VB1963.

    WinForms-DGV: Rohwert in der Datenquelle, Anzeige aber formatiert (mit Anhang) - Optimierungsmöglichkeit gesucht [gelöst]

    Hallo zusammen.

    Nun bin ich endlich mal in der leidlichen Situation angekommen, dass ich formatierte Rohdaten in nem DGV anzeigen lassen will. Mit der Option, dass man neue Werte als Rohdaten oder als formatierte Daten angeben kann. Eine Lösung hab ich. Aber ich frag mich und Euch, ob das Pfeil-Rücken-Brust-Auge ist:

    VB.NET-Quellcode

    1. Public Class FrmMain
    2. Private ReadOnly Foos As New List(Of Foo)
    3. Private ReadOnly Appendix As String = " Klicks"
    4. Private Enum ValueToSetWhenTypingBullshit
    5. DefaultValue
    6. PreviousValue
    7. End Enum
    8. Private ReadOnly CorrectedValue As ValueToSetWhenTypingBullshit = ValueToSetWhenTypingBullshit.DefaultValue
    9. Private Sub FrmMain_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    10. Foos.Add(New Foo With {.ClickCount = 23})
    11. BsFoos.DataSource = Foos
    12. End Sub
    13. Private Sub DgvFoos_CellFormatting(sender As Object, e As DataGridViewCellFormattingEventArgs) Handles DgvFoos.CellFormatting
    14. If e.Value IsNot Nothing AndAlso e.ColumnIndex = ColClickCount.DisplayIndex Then e.Value = e.Value.ToString & Appendix
    15. End Sub
    16. Private Sub DgvFoos_DataError(sender As Object, e As DataGridViewDataErrorEventArgs) Handles DgvFoos.DataError
    17. If CorrectedValue = ValueToSetWhenTypingBullshit.DefaultValue Then DgvFoos.CurrentCell.Value = 0 'nicht optimal, da Integer-spezifisch/nicht generisch
    18. e.Cancel = False
    19. End Sub
    20. Private Sub DgvFoos_CellParsing(sender As Object, e As DataGridViewCellParsingEventArgs) Handles DgvFoos.CellParsing
    21. If e.Value.ToString.EndsWith(Appendix) Then e.Value = Convert.ChangeType(e.Value.ToString.Replace(Appendix, Nothing), e.DesiredType) : e.ParsingApplied = True
    22. End Sub
    23. End Class
    24. Friend Class Foo
    25. Property ClickCount As Integer
    26. End Class

    Ergebnis:
    zu Beginn


    123 eingegeben + Enter


    42 Klicks eingegeben + Enter


    gar nix oder Blödsinn eingegeben + Enter
    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.
    @VB1963: Das hatte ich absichtlich gemacht, um "abstrakt" zu agieren - obwohl mir das noch nicht abstrakt genug ist, wie der Kommentar in der Zeile verrät. Dein Vorschlag funktioniert zwar, bindet mich aber noch stärker an die tatsächlichen Daten. Argh, das hätte ich natürlich erwähnen sollen, dass es mir um eine allgemeingültige Lösung geht.
    Ok, wenn Euch beiden Spezialisten keine weitere Verbesserung auf Anhieb in den Sinn kommt, dann werd ich das wohl dabei belassen. Ich hatte gedacht, dass ggf. mir noch jemand sagt: "Was'n das für ein Blödsinn? Das macht man doch heutzutage soundso. Hast Du denn gar nix gelernt, junger Pavian?" Oder Karawan. Oder wie diese spezielle Azubibezeichnung auch immer war :P
    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.
    Hab doch womöglich noch eine kleine Verbesserung(?)/Generalisierung gefunden. Mittels Festlegung von Format und NullValue der betroffenen Dgv-Spalte geht's noch anders:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Class FrmMain
    2. Private ReadOnly Foos As New List(Of Foo)
    3. Private ReadOnly Appendix As String = " Klicks"
    4. Private NullValue As Object = Nothing
    5. Private Enum ValueToSetWhenTypingBullshit
    6. DefaultValue
    7. PreviousValue
    8. End Enum
    9. Private ReadOnly CorrectedValue As ValueToSetWhenTypingBullshit = ValueToSetWhenTypingBullshit.DefaultValue
    10. Private Sub FrmMain_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    11. Foos.Add(New Foo With {.ClickCount = 23})
    12. Foos.Add(New Foo With {.ClickCount = 45})
    13. Foos.Add(New Foo With {.ClickCount = 0})
    14. BsFoos.DataSource = Foos
    15. NullValue = 0
    16. ColClickCount.DefaultCellStyle.NullValue = NullValue
    17. ColClickCount.DefaultCellStyle.Format = "#" & Appendix
    18. End Sub
    19. 'braucht es doch nicht, siehe Edit
    20. Private Sub DgvFoos_CellFormatting(sender As Object, e As DataGridViewCellFormattingEventArgs) Handles DgvFoos.CellFormatting
    21. If e.Value Is Nothing OrElse e.ColumnIndex <> ColClickCount.DisplayIndex OrElse e.Value.ToString <> NullValue.ToString Then Return
    22. e.Value = NullValue.ToString & Appendix
    23. e.FormattingApplied = True
    24. End Sub
    25. Private Sub DgvFoos_DataError(sender As Object, e As DataGridViewDataErrorEventArgs) Handles DgvFoos.DataError
    26. If CorrectedValue = ValueToSetWhenTypingBullshit.DefaultValue Then DgvFoos.CurrentCell.Value = NullValue
    27. e.Cancel = False
    28. End Sub
    29. Private Sub DgvFoos_CellParsing(sender As Object, e As DataGridViewCellParsingEventArgs) Handles DgvFoos.CellParsing
    30. If e.Value.ToString.EndsWith(Appendix) Then e.Value = Convert.ChangeType(e.Value.ToString.Replace(Appendix, Nothing), e.DesiredType) : e.ParsingApplied = True
    31. End Sub
    32. End Class
    33. Friend Class Foo
    34. Property ClickCount As Double
    35. End Class
    Minuspunkt: Wenn man den NullValue in der Zelle hat (eben weil man den Zellinhalt gelöscht hat oder Blödsinn eingegeben hat), muss man das explizit im CellFormatting-EH bearbeiten, weil sonst (Leerzeichen) Klicks in der Zelle steht. Hm … verdächtig, dass die 0 da nicht angezeigt wird. Da stimmt doch was mit den Einstellungen nicht.

    ##########

    Ah, gefunden: Steht bei .Format ein #, wird die Null wegrationalisiert. Also ColClickCount.DefaultCellStyle.Format = "0" & Appendix
    Und somit kann der komplette CellFormatting-EH weg :D

    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 2 mal editiert, zuletzt von „VaporiZed“ ()

    Ich hab's probiert und festgestellt, dass der 1. Eintrag mit 23 beim Laden des DGV das DataError-Event auslöst und somit 0 auspuckt...
    Den Eintrag mit 45 gibt er wie gewollt aus.
    Wenn die Zeile #20 auskommentiert wird, passt es auf einmal...
    Ist das bei dir auch so?

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

    Mit dem Code aus Post#1? Nö, da kommt bei mir zum Start ganz normal das mit 23 Klicks, siehe Post#1, Bild#1.
    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.
    Nö, kann ich auch da nicht nachvollziehen. Aber vielleicht ist was anderes eingestellt. Ich lad gleich mal mein Testprojekt hoch …

    ##########

    Projektupload erledigt
    Bilder
    • ResultWithUpdatedCode.png

      2,22 kB, 411×204, 43 mal angesehen
    Dateien
    • WinForms.zip

      (19,17 kB, 54 mal heruntergeladen, zuletzt: )
    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 2 mal editiert, zuletzt von „VaporiZed“ ()

    Klappt bei mir aber immer noch.
    Bilder
    • AllowAddingRows.png

      48,38 kB, 1.162×544, 40 mal angesehen
    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.
    Aber jetzt fehlen bei dir im Listing plötzlich wesentliche Zeilen?

    VB.NET-Quellcode

    1. Private ReadOnly CorrectedValue As ValueToSetWhenTypingBullshit = ValueToSetWhenTypingBullshit.DefaultValue
    fehlt!

    VB.NET-Quellcode

    1. Private Sub DgvFoos_DataError(sender As Object, e As DataGridViewDataErrorEventArgs) Handles DgvFoos.DataError
    2. If CorrectedValue = ValueToSetWhenTypingBullshit.DefaultValue Then DgvFoos.CurrentCell.Value = NullValue
    3. e.Cancel = False
    4. End Sub
    Zeile #2 fehlt!
    Ohne denen gehts bei mir auch...
    Ich rede immer noch von deinem Post #6 (Listing im Spoiler), wo du deine letzten Optimierungen gemacht hast...

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

    Argh, das kommt davon, wenn man zwischendurch modifiziert, um es in andere Programme einzubauen X/
    Einen Moment.

    ##########

    Aha. Es reicht wohl im DataError-EH was abzuändern: Den Zellbezug.

    VB.NET-Quellcode

    1. Private Sub DgvFoos_DataError(sender As Object, e As DataGridViewDataErrorEventArgs) Handles DgvFoos.DataError
    2. If CorrectedValue = ValueToSetWhenTypingBullshit.DefaultValue Then DgvFoos.Item(e.ColumnIndex, e.RowIndex).Value = NullValue
    3. e.Cancel = False
    4. End Sub

    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“ ()

    Ich hätte diesen Vorschlag:

    VB.NET-Quellcode

    1. Private Sub DgvFoos_DataError(sender As Object, e As DataGridViewDataErrorEventArgs) Handles DgvFoos.DataError
    2. 'If CorrectedValue = ValueToSetWhenTypingBullshit.DefaultValue Then DgvFoos.CurrentCell.Value = NullValue
    3. If DgvFoos.Rows(e.RowIndex).IsNewRow Then
    4. DgvFoos.Item(e.ColumnIndex, e.RowIndex).Value = Nothing
    5. Else
    6. If CorrectedValue = ValueToSetWhenTypingBullshit.DefaultValue Then
    7. DgvFoos.Item(e.ColumnIndex, e.RowIndex).Value = NullValue
    8. End If
    9. End If
    10. e.Cancel = False
    11. End Sub

    Sonst schaut es so aus: