MVVM Umsetzung mit WinForms

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

Es gibt 194 Antworten in diesem Thema. Der letzte Beitrag () ist von Amelie.

    Coldfire schrieb:

    ist die Verwendung von WinForms als Viewmodell als Strategie zu teuer?
    Das ergibt jetzt keinen Sinn, daher ignoriere ich das mal.

    Coldfire schrieb:

    Mein Argument pro MVVM wäre die Vermutung, dass es einfacher automatisierbar ist.
    Was meinst Du konkret mit automatisierbar? Sie sind - wenn man Models und ViewModels richtig gestaltet - automatisierbar testbar. Stichwort TDD (Also Test Driven Development, nicht Typed DataSet Driven Development ;) )
    a) nein, es wird umfangreicher
    b) wenn man einmal den Durchblick hat, ist es besser als Spaghetticode - Übungssache
    c) durch automatisierte Tests: ja
    d) ja, da Codeprinzipien à la Clean Code noch besser eingehalten werden können - wenn man sie denn anwendet
    e) dito
    f) wenn man erstmal geblickt hat, dass es eigentlich recht simpel ist, bleibt es das auch; was hab ich mir nen gedanklichen Abriss mit WPF und MVVM gemacht, bis ich geblickt habe, worum es einfacherweise wirklich geht …
    g) Wenn Models und ViewModels unabhängig vom View sind, ist man damit flexibler als mit einer ClassicWinForms-App: Das View ist ja austauschbar, kann also ne WPF-App, WinForms-App, Konsole, sonstewas sein. Aber plattformunabhängig? Keine Ahnung.
    h) Für ne 08/15-App, die auf eine Bildschirmseite passt, ist MVVM Overkill.

    Warum macht man WPF-Apps im MVVM-Stil? Warum nicht klassisch CodeBehind? Und die gleiche Doppel-Frage kann man bei WinForms genauso stellen. Für mich ist MVVM auch eine Möglichkeit, mehr über den Code nachzudenken, ihn sauberer zu gestalten und Dinge zu trennen, die nicht zusammengehören. Ich könnte auch alles in eine Form-Klasse und am besten noch alles in die EventHandler schreiben. Zurück ins Chaos meiner Anfangsjahre. Aber das ist natürlich Nonsens. Stattdessen: Aufräumen, Struktur schaffen, Dinge dorthin räumen, wo man sie wiederfinden und ggf. anpassen oder abändern kann. Das ist das Ziel und MVVM ist ein Weg dorthin. Ich sehe immer noch so viele Apps bei mir, bei denen in den Formklassen so viele Dinge geschehen, obwohl es einfach nicht die Aufgabe der Forms ist, sich um diesen Kram zu kümmern. Es sind IO-Klassen, Benutzerdaten rein, Anzeige raus! Und mehr nicht. Keine Berechnungen, keine Daten laden oder speichern, usw. usf. Es ist einfach nicht deren Job, sich um was anderes zu kümmern, als die Daten weiterzugeben (ans ViewModel oder an den Monitor) und das will ich zumindest beherzigen und umsetzen, Stichwort SRP.

    Amelie schrieb:

    Ich finde es äußerst verwirrend, wenn Code der in VS2017 / VS2019 noch funktionierte dann in VS2022 nicht mehr geht... Erwähnt ich hier auch schon, bzgl der Singelton Class ...
    Bei mir wird das nicht mit der Singleton-Klasse angezeigt. Mach mal bitte n Screenshot von der VS-Meckerei.
    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“ ()

    @Coldfire: Jo, das ist ja ein nettes Sortiment an Fragen. Die meisten Fragen verwenden den Komparativ. Dabei bleibt ungesagt, gegen was der Vergleich angestellt werden soll. Wenn gegen den Pattern "Alles ins CodeBehind" verglichen werden soll, so muss man für banale Programme die meisten Fragen verneinen, aber ab einer gewissen Komplexität (ungefähr mehr als 1 Form/UserControl, bzw mehr als 500 Zeilen) wird MVVM günstiger, und ab mittelgrosse Anwendung kommt man mit "Alles ins CodeBehind" ja garnet mehr zurande.
    Aber ich lege dir meinen CodePattern vor, der sich bei mir seit ca. 10 Jahren herauskristallisiert: "Dataset driven Development" habich das genannt, "DDD".
    Das löst dieselben Probleme, die MVVM zu lösen versucht, in Wpf mit Erfolg, in WinForms - naja, unter unverhältnismässigem Mehraufwand.
    Also Vergleich WinForms-MVVM - DDD:

    a) ist der Code dadurch übersichlicher / einfacher?
    nein, DDD ist deutlich übersichlicher / einfacher
    b) ist die Wartbarkeit besser ?
    nein, DDD ist deutlich besser wartbar
    c) ist die Implementierung der Funktionalitäten damit weniger fehleranfällig ?
    da liegen sie wohl gleich, aber in MVVM ist schwieriger sich zu orientieren
    d) ist die Erweiterbarkeit des Codes dadurch besser ?
    wohl gleich
    e) geht das Implementieren schneller?
    DDD ist deutlich! schneller
    f) wie hoch sind die Lernhürden (Dichte und Anzahl der Fachbegriffe, die die Erlärungen spicken) ?
    DDD basiert auf typisiertem Dataset, und das basiert auf relationaler Datenmodellierung.
    mit MVVM kann man sich beliebige Datenmodelle zurechtwursteln, und gelegentlich schön auf die Nase fallen.
    Dann wird man auch für MVVM relationale Datenmodellierung erlernen müssen - sie allerdings umzusetzen ist nicht in jedem Falle möglich.
    Also beim MVVM-Lernen kann man an relationaler Datenmodellierung "vorbeirennen", was einen aber böse einholt.
    MVVM hat einen Haufen eigenen Lernstoff, allerdings recht schwammig, "was ist/darf viewmodel?, was ist/darf model?, und was für Hilfs-Konstruktionen müssemer auffahren, um am Ende dennoch zu erreichen, was die Anwendung tun soll?
    Das typDataset hingegen ist eine klare Sache: Man bastelt sich eines, dann kann man es untersuchen, und seine Eigenschaften kennenlernen.
    g) wie sieht es mit der multiplattformunterstützung aus ?
    äh - WinForms? mau.
    h) gibt es Einschränkungen, die die Implementierung unmöglich machen bzw ad absurdum führt ? (spezielle Controls,..)
    Wie gesagt: Für Winz-Anwendungen lohnt sich das nicht.
    DDD lohnt sich, sobald eine Liste von Daten abzuspeichern und zu laden ist
    MVVM lohnt sich erst bei komplexeren Anwendungen.

    Übrigens, Testbarkeit: Ein typisiertes Dataset (inklusive aller Erweiterungen, die DDD ihm "antut") ist ebensogut unit-testbar wie ein ViewModel.

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

    @VaporiZed

    Kleines Update und eine Frage.

    Ich habe das mit den "3 einzelnen DGVs und Charts" aufgegeben und den Vorschlag von @ErfinderDesRades mit der ComboBox aufgegriffen.
    So habe ich dann nur noch 2 TabReiter, einen für das DGV (DatenAnzeige / DatenEingabe) und einen für das spätere Chart.
    In der Combobox stehen dann die Namen drin, welche man in den Einstellungen vergibt. Z.B. "Sauna, Kinderzimmer ..." ;)

    Jetzt eine Frage zu den Berechnungen:
    Spoiler anzeigen

    Das ClimaModel

    VB.NET-Quellcode

    1. '/ file: ClimaModel.vb
    2. <Serializable>
    3. Public Class ClimaModel
    4. Public Property ID As Integer
    5. Public Property RecordUnit As Integer
    6. Public Property LocalDateTime As DateTime
    7. Public Property Temperatur1 As Double
    8. Public Property Temperatur2 As Double
    9. Public Property Temperatur3 As Double
    10. Public Property Humidity1 As Double
    11. Public Property Humidity2 As Double
    12. Public Property Humidity3 As Double
    13. End Class


    Das Model für die Durchschnittswerte

    VB.NET-Quellcode

    1. Public Class AvgClimaModel
    2. ' Einzel Durchschnitt
    3. Public Property AgvTemperatur1 As Double
    4. Public Property AgvTemperatur2 As Double
    5. Public Property AgvTemperatur3 As Double
    6. Public Property AgvHumidity1 As Double
    7. Public Property AgvHumidity2 As Double
    8. Public Property AgvHumidity3 As Double
    9. ' Gesammt Durchschnitt
    10. Public Property MeanTemperatur As Double
    11. Public Property MeanHumidity As Double
    12. End Class



    Brauche ich für die Durchschnittswerte denn ein Model ??? Bin mir da gerade unsicher...
    Gibt es einen "einfachen Weg" die ganzen Durchschnitte zu ermitteln?
    danke


    PS: Screeshoot bzgl des 2022 gemeckeres mach ich dann mal..
    Bilder
    • update1.jpg

      914,73 kB, 1.695×804, 32 mal angesehen
    • update2.jpg

      284,07 kB, 885×471, 30 mal angesehen
    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:

    Amelie schrieb:

    Brauche ich für die Durchschnittswerte denn ein Model ???
    Nein. Welche Klasse weiß von allen ClimaModels? Jene Klasse darf gerne auch die Berechnungen durchführen und sie dem View zur Verfügung stellen. Das kann also m.E. gerne ins MainViewModel. Denn andere ViewModels werden zwar vielleicht auch die Rohdaten verwenden. Aber nicht auf jedem View wird die Durchschnittstemperatur benötigt.
    ClimaModel … die Benennung find ich ausbaufähig. Dass da was modelliert wird und ein digitales Abbild von einer realen, wenn auch abstrakten Sache geschaffen wird, muss sich nicht im Namen widerspiegeln. Das ist eine Redundanz. Aber was wird modelliert/digitalisiert? Ein Clima? Nee, eigentlich eine Messung, also quasi Measurement oder spezifischer WeatherMeasurement. Aber es ist Dein Kind und Du kannst es benennen, wie Du willst.
    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.
    @VaporiZed
    Habe das Projekt angehangen. Das bleibt nun auch so, nur immer mit dem "v1/v2/...am Ende. Bzgl der Versionen die noch funktionierten. ;)
    Aber da sind noch meine ganzen DebugAusgaben drin, damit ich sehen kann, was alles OHNE eine GUI läuft.

    Den Namen habe ich mit Absicht so gewählt, weil ich den ganzen anderen Versionen mit dem DataSets aus dem Designer hatte ich die "Messuremnts" drin und muss die aus dem Kopf bekommen. <X

    Ich hätte nun gedacht dafür ein seperates "VM" zu machen... oder eine weitere Partial der VM_Main... hmmmm


    Dateianhänge entfernt, weil nicht mehr auf dem neusten Stand.
    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:

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

    Ein separates VM? Bedenke, dass das VM unter anderem dazu dient, Daten mindestens eines Views aufzubereiten. Zwei VMs für ein View ist m.E. Murks. Das kann bedenkenlos inst MainViewModel. Und ob Du für die Berechnungen ne eigene Partial File verwendest: Warum nicht? Mach ruhig, wenn es Dir bei der Übersicht hilft.
    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.
    Noch nicht. ich hab grad zu wenig Zeit und melde mich wohl diesbezüglich morgen. Für die Analyse eines fremden Projektes reichen mir keine 10 Minuten.

    ##########

    @Amelie:
    Folgende Klassen im Ordner Models haben komische Namen: CreateTemplate, LoadDataSet, SaveDataSet. Das sind eher Methodennamen. Außerdem gehören sie eher in den Ordner Varios. Inhaltlich gehören SaveDataSet und LoadDataSet zusammen in eine Klasse.
    ClimaModel - ja, das ist eine Modelklasse.
    Bei AvgClimaModel hatte ich ja schon die Frage beantwortet, dass die Klasse nicht nötig ist.

    Configuration ist auch eine Modelklasse
    Ist ConfigViewModel absichtlich nicht im Ordner ViewModels?
    SaveLoadConfigModel würde auch in Varios gehören, aber vielleicht hast Du die ganzen ConfigSachen auch absichtlich in einen eigenen Ordner geschoben.

    FrmMain kennt das ConfigViewModel. Wozu? Es wird nicht in der Klasse benötigt oder darauf verwiesen.

    VB.NET-Quellcode

    1. Private Sub UpdateCurrentMonth()
    2. TxtMonthMenuItem.Text = _mainVM_Instance.CurrentMonth.ToString("MMMM yyyy")
    3. End Sub
    Das ist MVVM-mäßig mit DataBinding umzusetzen.

    VB.NET-Quellcode

    1. Private Sub UpdateEvents()
    2. LblEvents.DataBindings.Add(New Binding("Text", _mainVM_Instance, NameOf(_mainVM_Instance.Eventmessage), True, DataSourceUpdateMode.OnPropertyChanged))
    3. End Sub
    plus der meiste Code in FrmConfig: Puh, Du sträubst Dich aufgrund des BindingBugs echt gegen den Einsatz einer Designer-BindingSource, oder?

    andere Sachen

    VB.NET-Quellcode

    1. Private Sub BindStationNamesToComboBox()
    2. CmbStation.DataSource = Nothing
    3. CmbStation.DataSource = _mainVM_Instance.StationNames.ToList()
    4. End Sub
    Wozu das Setzen von Nothing?

    VB.NET-Quellcode

    1. Private Sub BtnExitMenuItem_Click(sender As Object, e As EventArgs) Handles BtnExitMenuItem.Click
    2. 'BackUp
    3. Application.Exit()
    4. End Sub
    Warum nicht einfach Close?

    VB.NET-Quellcode

    1. Private Sub SaveDatas()
    2. DgvClimaData.EndEdit()
    3. _mainVM_Instance.SaveDatasRelayCommand.Execute(Nothing)
    4. End Sub
    Wozu EndEdit? Das Verlassen des DGVs durch Klicken eines Buttons etc beendet automatisch den Bearbeitungsmodus des DGVs.
    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“ ()

    Danke für das Feedback @VaporiZed

    ​DgvClimaData.EndEdit()
    Ohne dem wurde aber nichts gespeichert!

    ​Du sträubst Dich aufgrund des BindingBugs echt
    Bevor mir wieder und wieder immer alles "verloren" geht, mache ich es halt so. Nicht ganz "MvvM WF" aber naja :)

    ​hast Du die ganzen ConfigSachen auch absichtlich
    Ja in der Tat war das Absicht. :)

    FrmMain kennt das ConfigViewModel. Wozu?
    Vielleicht brauche ich da da nochmal????

    ​Application.Exit()
    Hab mal irgendwo gelesen, soll besser sein als nur Close.
    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:

    Amelie schrieb:

    Ohne dem wurde aber nichts gespeichert!
    Da hast Du recht. Da verhält sich ein ToolStripItem leider anders als ein Button. Das hatte ich bei meinem Test nicht beachtet. Der EditMode wird beim ToolStripClick tatsächlich nicht verlassen, weil der Eingabefokus nicht verloren geht.

    Amelie schrieb:

    Bevor mir wieder und wieder immer alles "verloren" geht, mache ich es halt so.
    Leider zählt dieses Argument nicht, solange Du ein .NET-Fx Projekt hast ;) In .NET-Apps gibt es den Bug noch, aber Du hast ja schon ne Weile Dir ein .NET-Fx-Projekt angelegt. Da hab ich das Problem noch nicht feststellen/nachbauen können. Probier es einfach mal in einer Testapp mit .NET-Fx 4.5 oder 4.8.

    Das mit der Sortierung solltest Du dann aber etwas vereinheitlichen, weil Du einen Ordner ViewModels und Models hast und dann eben noch Config, wo Du dann aber spezifische Models und ViewModels drinhast.

    Amelie schrieb:

    Vielleicht brauche ich da da nochmal????
    1. nein, da das ConfigViewModel nichts im MainView zu suchen hat, genauso wie grundsätzlich Viewfremde ViewModels nicht auftauchen sollten.
    2. Für den Fall, dass Du es glaubst, es wirklich zu brauchen: Bau es dann ein, wenn es wirklich soweit ist und frag Dich/uns vorher, ob das zu lösende Problem besser lösbar ist. Ich kann keinen Grund bisher finden, ViewModelX in ViewY zu haben.

    Amelie schrieb:

    Hab mal irgendwo gelesen, soll besser sein als nur Close.
    Wenn Du ne Quelle hast, immer her damit. Da Deine App so gebaut ist, dass das Programm beendet wird, wenn das MainForm geschlossen wird, brauchst Du Dich nicht explizit um das Aufräumen zu kümmern. Außerdem finde ich die Aussage von Microsoft jetzt nicht so dolle:

    Microsoft schrieb:

    Die Exit-Methode beendet alle ausgeführten Nachrichtenschleifen in allen Threads und schließt alle Fenster der Anwendung. Diese Methode erzwingt nicht unbedingt das Beenden der Anwendung.

    Application.Exit könnte man verwenden, wenn man von irgendeiner Stelle im Code das Programm beenden will. Aber sowas hab ich noch nicht benötigt. Der normale Werdegang ist ja, dass man alle Forms schließt, wenn man die ganze Zeit mit ShowDialog alle SubForms kreiert. Würde man mit multiplen gleichberechtigten Forms arbeiten, also mit Show statt mit ShowDialog, ist es schon eine Option, dass man auf einem oder mehreren Forms die Option haben will, die ganze App zu schließen. Aber sowas hast Du ja nicht. Du hast ein MainForm und die anderen Forms erzeugst Du mit ShowDialog. Daher ist Application.Exit bei Dir überflüssig.
    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 4 mal editiert, zuletzt von „VaporiZed“ ()

    @VaporiZed
    Moin moin

    Habe nun das mit den Durchschnittswerten hinbekommen.

    Der Code:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. '/ file: AvgCalculationen.vb
    2. Public Class AvgCalculationen
    3. Private AvgValues As New AvgClimaModel
    4. Public Function CalculateAverages(climaData As List(Of ClimaModel)) As AvgClimaModel
    5. Dim totalTemperatur1 As Double = 0
    6. Dim totalTemperatur2 As Double = 0
    7. Dim totalTemperatur3 As Double = 0
    8. Dim totalHumidity1 As Double = 0
    9. Dim totalHumidity2 As Double = 0
    10. Dim totalHumidity3 As Double = 0
    11. Dim countTemperatur1 As Integer = 0
    12. Dim countTemperatur2 As Integer = 0
    13. Dim countTemperatur3 As Integer = 0
    14. Dim countHumidity1 As Integer = 0
    15. Dim countHumidity2 As Integer = 0
    16. Dim countHumidity3 As Integer = 0
    17. ' Debug-Ausgaben zum Überprüfen der Daten
    18. Debug.WriteLine("Berechnung der Durchschnittswerte gestartet.")
    19. For Each datas In climaData
    20. ' Temperaturen und Feuchtigkeiten nur berücksichtigen, wenn sie nicht gleich 0 sind
    21. If datas.Temperatur1 <> 0 Then
    22. totalTemperatur1 += datas.Temperatur1
    23. countTemperatur1 += 1
    24. End If
    25. If datas.Temperatur2 <> 0 Then
    26. totalTemperatur2 += datas.Temperatur2
    27. countTemperatur2 += 1
    28. End If
    29. If datas.Temperatur3 <> 0 Then
    30. totalTemperatur3 += datas.Temperatur3
    31. countTemperatur3 += 1
    32. End If
    33. If datas.Humidity1 <> 0 Then
    34. totalHumidity1 += datas.Humidity1
    35. countHumidity1 += 1
    36. End If
    37. If datas.Humidity2 <> 0 Then
    38. totalHumidity2 += datas.Humidity2
    39. countHumidity2 += 1
    40. End If
    41. If datas.Humidity3 <> 0 Then
    42. totalHumidity3 += datas.Humidity3
    43. countHumidity3 += 1
    44. End If
    45. Next
    46. ' Durchschnittswerte berechnen
    47. AvgValues.AgvTemperatur1 = If(countTemperatur1 > 0, totalTemperatur1 / countTemperatur1, 0)
    48. AvgValues.AgvTemperatur2 = If(countTemperatur2 > 0, totalTemperatur2 / countTemperatur2, 0)
    49. AvgValues.AgvTemperatur3 = If(countTemperatur3 > 0, totalTemperatur3 / countTemperatur3, 0)
    50. AvgValues.AgvHumidity1 = If(countHumidity1 > 0, totalHumidity1 / countHumidity1, 0)
    51. AvgValues.AgvHumidity2 = If(countHumidity2 > 0, totalHumidity2 / countHumidity2, 0)
    52. AvgValues.AgvHumidity3 = If(countHumidity3 > 0, totalHumidity3 / countHumidity3, 0)
    53. ' Gesamtdurchschnittswerte berechnen
    54. AvgValues.MeanTemperatur = (AvgValues.AgvTemperatur1 + AvgValues.AgvTemperatur2 + AvgValues.AgvTemperatur3) / 3
    55. AvgValues.MeanHumidity = (AvgValues.AgvHumidity1 + AvgValues.AgvHumidity2 + AvgValues.AgvHumidity3) / 3
    56. ' Debug-Ausgaben zur Überprüfung der berechneten Durchschnittswerte
    57. Debug.WriteLine($"Durchschnittstemperaturen: Temp1={AvgValues.AgvTemperatur1}, Temp2={AvgValues.AgvTemperatur2}, Temp3={AvgValues.AgvTemperatur3}")
    58. Debug.WriteLine($"Durchschnittliche Feuchtigkeit: Hum1={AvgValues.AgvHumidity1}, Hum2={AvgValues.AgvHumidity2}, Hum3={AvgValues.AgvHumidity3}")
    59. Debug.WriteLine($"Gesamtdurchschnittstemperatur: {AvgValues.MeanTemperatur}")
    60. Debug.WriteLine($"Gesamtdurchschnittliche Feuchtigkeit: {AvgValues.MeanHumidity}")
    61. Return AvgValues
    62. End Function
    63. End Class


    Im MainViewModel: ( was neu dazugekommen ist )

    VB.NET-Quellcode

    1. Private Sub LoadDatas()
    2. ' Lade die Daten als List(Of ClimaModel)
    3. Dim climaModelsList As List(Of ClimaModel) = LoadXmlInstance.LoadFromXml()
    4. ' Konvertiere die List(Of ClimaModel) in eine BindingList(Of ClimaModel)
    5. AllClimaModels = New BindingList(Of ClimaModel)(climaModelsList)
    6. ' Berechne die Durchschnittswerte
    7. CalculateAverages()
    8. End Sub
    9. ' Berechne Durchschnittswerte
    10. Public Sub CalculateAverages()
    11. Dim avgCalc As New AvgCalculationen()
    12. AvgClimaModel = avgCalc.CalculateAverages(AllClimaModels.ToList())
    13. End Sub
    14. ' Durchschnittswerte
    15. Private _avgClimaModel As New AvgClimaModel()
    16. Public Property AvgClimaModel As AvgClimaModel
    17. Get
    18. Return _avgClimaModel
    19. End Get
    20. Set(value As AvgClimaModel)
    21. If _avgClimaModel IsNot value Then
    22. _avgClimaModel = value
    23. OnPropertyChanged(NameOf(AvgClimaModel))
    24. End If
    25. End Set
    26. End Property
    27. Public ReadOnly Property MeanTemperatur As Double
    28. Get
    29. Return AvgClimaModel.MeanTemperatur
    30. End Get
    31. End Property
    32. Public ReadOnly Property MeanHumidity As Double
    33. Get
    34. Return AvgClimaModel.MeanHumidity
    35. End Get
    36. End Property
    37. ' Formatierte Properties für die Anzeige der GUI
    38. Public ReadOnly Property FormattedMeanTemperatur As String
    39. Get
    40. Debug.WriteLine($"Temp: {MeanTemperatur}")
    41. Return $"{AvgClimaModel.MeanTemperatur:N1} °C"
    42. End Get
    43. End Property
    44. Public ReadOnly Property FormattedMeanHumidity As String
    45. Get
    46. Debug.WriteLine($"Humidi: {MeanHumidity}")
    47. Return $"{AvgClimaModel.MeanHumidity:N0} %"
    48. End Get
    49. End Property



    Probier es einfach mal in einer Testapp mit .NET-Fx 4.5 oder 4.8.

    Werde ich machen, wenn ich das hier fertig habe!

    Die ConfigViewModel ist aus dem FrmMain verschwunden :)

    Das mit dem "Application Exit" bezog sich galube ich wirklich auf Form die mit "Show" und nicht "ShowDialog" erstellt werden.

    Jetzt fehlen hier nun noch das Chart und dann das ausdrucken der "Tabellen & Chart" :) Wobei das Chart wohl einfacher wird...??
    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:
    @VaporiZed

    So habe nun alles fertig. :)
    Anzeige in den DGVs und des Chart funktionieren, incl. der Stationsauswahl über die ComboBox und das blättern der Monate.
    Ebenso das anzeigen im Chart (Einzel,- Gesamtwerte) sowie das ausdrucken von Charts und Tabellen.

    Jetzt mal in einem längeren Zeitraum testen. :)
    Bilder
    • PolyClima1.jpg

      224,69 kB, 456×759, 27 mal angesehen
    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:
    Kommt da noch was oder hast Du Dich (hoffentlich nicht schon wieder) verheddert?
    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.
    @VaporiZed

    Hier ist erstmal Pause, weil ich das ganze Prog soweit fertig ist und läuft und ich es nun mal in Echtzeit von Opa testen lasse.
    Bisher läuft es besser als meine erste "SpaghettiCode-Version" ;)
    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh: