MVVM Umsetzung mit WinForms

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

Es gibt 173 Antworten in diesem Thema. Der letzte Beitrag () ist von VaporiZed.

    @VaporiZed

    Kleines Update zu meinem "MvvM" Projekt.
    Alles schön in Views / ViewModel / Model mit dem kleinen "workarround" das nur noch sehr sehr wenig Code auf dem Form ist.

    Das Form mit dem Code.
    Die 2 ButtonSubs mit dem Print mache ich morgen noch mit dem RelayCommand :!:

    Das umschalten des Chart von Balken auf Linien funktioniert auch, ebenso das drucken der Tabellen / Chart. :)

    Spoiler anzeigen

    VB.NET-Quellcode

    1. '/ file: FrmShowDatas.vb
    2. Imports System.ComponentModel
    3. Public Class FrmShowDatas
    4. Private ReadOnly DataVMInstance As DailyDataViewModel = DailyDataViewModel.Instance
    5. Private ReadOnly GraphVMInstance As GraphViewModel = GraphViewModel.Instance
    6. Private ReadOnly DgvFormater As New DgvFormater()
    7. Public Sub New()
    8. InitializeComponent()
    9. DGV_MonthMeasurements.AutoGenerateColumns = False
    10. DGV_DailyMeasurements.AutoGenerateColumns = False
    11. AddHandler DGV_MonthMeasurements.CellFormatting, AddressOf DgvFormater.CellFormattingMonthly
    12. AddHandler DGV_DailyMeasurements.CellFormatting, AddressOf DgvFormater.CellFormattingDaily
    13. End Sub
    14. Private Sub FrmShowDatas_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    15. BindDGVs()
    16. BindChart()
    17. BindAverageLabels()
    18. End Sub
    19. Private Sub BalkenLinienMenuItem_Click(sender As Object, e As EventArgs) Handles BalkenLinienMenuItem.Click
    20. GraphVMInstance.ToggleChartParameterRelayCommand.Execute(ChartDailyValues)
    21. End Sub
    22. Private Sub ChartDruckMenuItem_Click(sender As Object, e As EventArgs) Handles ChartDruckMenuItem.Click
    23. Dim printer As New PrintChart(ChartDailyValues)
    24. printer.Print()
    25. End Sub
    26. Private Sub TabDruckMenuItem_Click(sender As Object, e As EventArgs) Handles TabDruckMenuItem.Click
    27. Dim printer As New PrintTabelle
    28. printer.PrintFromXml()
    29. End Sub
    30. Private Sub BindDGVs()
    31. ' Laden und Zuweisen der monatlichen Messdaten
    32. DataVMInstance.LoadMonthlyMeasurements()
    33. DGV_MonthMeasurements.DataSource = DataVMInstance.MeasurementsBS
    34. ' Laden und Zuweisen der täglichen Messdaten
    35. DataVMInstance.LoadDailyMeasurements()
    36. DGV_DailyMeasurements.DataSource = DataVMInstance.DailyMeasurementsBS
    37. ' Sortierung für beide DataGridViews
    38. DgvFormater.SortDataGridViewDirectly(DGV_MonthMeasurements, DGV_DailyMeasurements)
    39. End Sub
    40. Private Sub BindChart()
    41. ' Laden der täglichen Daten für die Grafik
    42. GraphVMInstance.LoadDailyData()
    43. GraphVMInstance.UpdateChart(ChartDailyValues)
    44. GraphVMInstance.FormatChartAxisByMonthDays(ChartDailyValues)
    45. End Sub
    46. Private Sub BindAverageLabels()
    47. ' Anzeigen der Durchschnittwerte
    48. LblAvgTemp.DataBindings.Add(New Binding("Text", DataVMInstance, NameOf(DataVMInstance.RndAvgTemperatur), True, DataSourceUpdateMode.OnPropertyChanged))
    49. LblAvgHumidi.DataBindings.Add(New Binding("Text", DataVMInstance, NameOf(DataVMInstance.RndAvgHumidi), True, DataSourceUpdateMode.OnPropertyChanged))
    50. LblAvgPressure.DataBindings.Add(New Binding("Text", DataVMInstance, NameOf(DataVMInstance.RndAvgPresure), True, DataSourceUpdateMode.OnPropertyChanged))
    51. End Sub
    52. Private Sub FrmShowDatas_Closing(sender As Object, e As CancelEventArgs) Handles Me.Closing
    53. RemoveHandler DGV_MonthMeasurements.CellFormatting, AddressOf DgvFormater.CellFormattingMonthly
    54. RemoveHandler DGV_DailyMeasurements.CellFormatting, AddressOf DgvFormater.CellFormattingDaily
    55. End Sub
    56. End Class

    Bilder
    • app-1.jpg

      784,29 kB, 1.533×708, 21 mal angesehen
    • app-2.jpg

      320,88 kB, 1.044×612, 24 mal angesehen
    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:
    Hm. Sehe ich da die ViewModelDatei mit einem Methodennamen beginnend mit Frm? Und darin enthalten RemoveHandler? Falls ja: kein gutes Omen.
    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.

    Neu

    @VaporiZed

    Methodennamen beginnend mit Frm?


    Nein das ist die Form-Class. Besser habe ich das nicht bzgl, des " Binding-Problems " hinbekommen.

    Das mit dem "RemoveHandler" habe ich so gelesen, das man die auch wieder entfernen soll wegen "Speicherleaks" ?(




    Moin moin

    Kleines Update zum Code von gestern.
    Das "ViewModel" für die Form habe ich nun in mehrere Partial-Classes aufgeteilt.

    Spoiler anzeigen

    Update des Forms ( View ) und des Code Behinds.

    VB.NET-Quellcode

    1. '/ file: FrmShowDatas.vb
    2. Imports System.ComponentModel
    3. Public Class FrmShowDatas
    4. Private ReadOnly dgvs As Tuple(Of DataGridView, DataGridView)
    5. Public Sub New()
    6. InitializeComponent()
    7. dgvs = New Tuple(Of DataGridView, DataGridView)(DGV_MonthMeasurements, DGV_DailyMeasurements)
    8. End Sub
    9. Private Sub FrmShowDatas_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    10. ShowDataViewModel.Instance.CallDgvAutoColParameterRelayCommand.Execute(dgvs)
    11. BindDGVs()
    12. BindChart()
    13. BindAverageLabels()
    14. End Sub
    15. Private Sub BindDGVs()
    16. ' Laden der monatlichen und täglichen Daten für die DGVs
    17. ShowDataViewModel.Instance.CallDgvDatasParameterRelayCommand.Execute(dgvs)
    18. End Sub
    19. Private Sub BindChart()
    20. ' Laden der täglichen Daten für die Grafik
    21. ShowDataViewModel.Instance.CallChartParameterRelayCommand.Execute(ChartDailyValues)
    22. End Sub
    23. Private Sub BindAverageLabels()
    24. ' Anzeigen der Durchschnittwerte
    25. LblAvgTemp.DataBindings.Add(New Binding("Text", ShowDataViewModel.Instance, NameOf(ShowDataViewModel.Instance.RndAvgTemperatur), True, DataSourceUpdateMode.OnPropertyChanged))
    26. LblAvgHumidi.DataBindings.Add(New Binding("Text", ShowDataViewModel.Instance, NameOf(ShowDataViewModel.Instance.RndAvgHumidi), True, DataSourceUpdateMode.OnPropertyChanged))
    27. LblAvgPressure.DataBindings.Add(New Binding("Text", ShowDataViewModel.Instance, NameOf(ShowDataViewModel.Instance.RndAvgPresure), True, DataSourceUpdateMode.OnPropertyChanged))
    28. End Sub
    29. Private Sub BalkenLinienMenuItem_Click(sender As Object, e As EventArgs) Handles BalkenLinienMenuItem.Click
    30. ShowDataViewModel.Instance.ToggleChartParameterRelayCommand.Execute(ChartDailyValues)
    31. End Sub
    32. Private Sub ChartDruckMenuItem_Click(sender As Object, e As EventArgs) Handles ChartDruckMenuItem.Click
    33. ShowDataViewModel.Instance.PrintChartParameterRelayCommand.Execute(ChartDailyValues)
    34. End Sub
    35. Private Sub TabDruckMenuItem_Click(sender As Object, e As EventArgs) Handles TabDruckMenuItem.Click
    36. ShowDataViewModel.Instance.PrintTablesRelayCommand.Execute(Nothing)
    37. End Sub
    38. Private Sub FrmShowDatas_Closing(sender As Object, e As CancelEventArgs) Handles Me.Closing
    39. ShowDataViewModel.Instance.CallDgvRemoveHandlerParameterRelayCommand.Execute(dgvs)
    40. End Sub
    41. End Class



    Beiträge zusammengefasst ~VaporiZed
    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:

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

    Neu

    Amelie schrieb:

    Nein das ist die Form-Class
    Najaaa, aber Dein Screenshot sagt, dass Du die Datei LoadProcessWeatherData.vb im Ordner Models ausgewählt hast und angezeigt bekommst:

    Und wenn dem so ist, wär das ganz schönes Codemischmasch.

    Zum Thema RemoveHandler hatte ich mal was rausgesucht. Schlussfolgerung: brauchste normalerweise nicht.

    ##########

    Ich glaube zwar irgendwie nicht, dass Du den Form-BehindCode brauchst, aber bitte.
    Das mit dem Tuple versteh ich auch nicht.
    • Die Tuple-Klasse kannst Du ersetzen. (Dgv1, Dgv2) ergibt auch ohne Klasse ein Tupel.
    • Warum ein Tupel, warum keine 2 Parameter oder ein IEnumerable(Of DataGridView)?
    • Warum übergibst Du Controls ans ViewModel? Das ist ein MVVM-Bruch
    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“ ()

    Neu

    Hallo @VaporiZed

    Dein link mit dem RemoveHandler lese ich nachher mal. :thumbup:

    Ja in der Übersicht ist wohl etwas durch einander gerutscht, aber nicht nur da.

    Als ich das ganze neu begonnen hatte, eben wegen der Probleme mit dem Binding, habe ich beim erstellen nicht aufgepasst.

    Das ganze "MvvM" was ich bis jetzt hier gemacht habe, und was auch soweit läuft :rolleyes:


    ... ;( <X :whistling: ... ( warum gibts hier nicht die 3 Affen ) ... "asche auf mein..."


    Naja, das ganze ist nicht in ".Net 8" sondern in ".Net 4.8 FrameWork"

    OK die Arbeit war nicht ganz umsonst. Habe wieder einiges gelernt und das ganze "MvvM" besser verstanden.


    PS: Nachtrag zum Remove...
    Habe das sonst auch nie gemacht. Und die ersten Zeilen im dem Beitrag, da finde ich mich wieder. "Angst das ohne alles Murks wird" ;-)
    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:

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

    Neu

    Der relevante, mir bekannte MVVM-Unterschied in den Möglichkeiten zwischen .NET-FX und .NET: in .NET-Fx brauchst Du die Menübutton- und Button-Eventhandler, um die (Relay)Commands des VM aufzurufen, in .NET nicht.
    Alles andere dürfte nicht im CodeBehind der Forms sein.
    Du hattest die Tupel-fragen noch nicht beantwortet, allem voran: Warum werden dem VM DGVs übergeben?

    btw:

    Amelie schrieb:

    warum gibts hier nicht die 3 Affen
    könntest Du als Bild im Fließtext einfügen:
    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“ ()

    Neu

    Also folgendes. Ich habe 2 Dateien mit dem RelayCommand. In einer davon kann ich einen Parameter mit übergeben. Fand ich paraktisch. Dann stellte sich herraus, das ich eben NUR einen mit übergeben kann.
    Jetzt war die Überlegung, ok, 2 DGVs dann halt für so ziemlich alles 2 Subs....

    Oh nein, dann wir mir der Kopf abgerissen bgzl Redundanter Code.. Also erinnerte ich mich wieder an die tuple... ;)

    Aus dem "ViewModel" wo ich die ganzen Sachen für die beiden DGVs ( siehe bild von # 141 ) gemacht habe um das alles vom "View" zu trennen.
    So konnte ich die beiden DGVs in einem übergeben:

    VB.NET-Quellcode

    1. Private Sub BindDGVs()
    2. ' Laden der monatlichen und täglichen Daten für die beiden DGVs
    3. ShowDataViewModel.Instance.CallDgvDatasParameterRelayCommand.Execute(dgvs)
    4. End Sub



    Auszug aus dem "ViewModel" (Parital Class)
    Spoiler anzeigen

    VB.NET-Quellcode

    1. '/ file: P2_SDV_DgvFormater.vb
    2. ' Genau Werte und Farben werden noch gesetzt
    3. Partial Public Class ShowDataViewModel
    4. Public Property CallDgvDatasParameterRelayCommand As New ParameterRelayCommand(AddressOf LoadDGVDatas)
    5. Private Sub LoadDGVDatas(parameter As Object)
    6. Dim tuple As Tuple(Of DataGridView, DataGridView) = TryCast(parameter, Tuple(Of DataGridView, DataGridView))
    7. If tuple IsNot Nothing Then
    8. Dim dgvMonth As DataGridView = tuple.Item1
    9. Dim dgvDaily As DataGridView = tuple.Item2
    10. DailyDataViewModel.Instance.LoadMonthlyMeasurements()
    11. DailyDataViewModel.Instance.LoadDailyMeasurements()
    12. dgvMonth.DataSource = DailyDataViewModel.Instance.MeasurementsBS
    13. dgvDaily.DataSource = DailyDataViewModel.Instance.DailyMeasurementsBS
    14. SortDataGridViewDirectly(dgvMonth, dgvDaily)
    15. InitializeDataGridViewHandlers(dgvMonth, dgvDaily)
    16. End If
    17. End Sub
    18. Public Sub InitializeDataGridViewHandlers(monthlyDgv As DataGridView, dailyDgv As DataGridView)
    19. AddHandler monthlyDgv.CellFormatting, AddressOf CellFormattingMonthly
    20. AddHandler dailyDgv.CellFormatting, AddressOf CellFormattingDaily
    21. End Sub
    22. Public Sub SortDataGridViewDirectly(dgvMonth As DataGridView, dgvDaily As DataGridView)
    23. dgvMonth.Sort(dgvMonth.Columns("LocalObservationDateTime"), System.ComponentModel.ListSortDirection.Descending)
    24. dgvDaily.Sort(dgvDaily.Columns("Datum"), System.ComponentModel.ListSortDirection.Descending)
    25. End Sub
    26. Public Property CallDgvAutoColParameterRelayCommand As New ParameterRelayCommand(AddressOf DataGridViewAutoCol)
    27. Public Sub DataGridViewAutoCol(parameter As Object)
    28. Dim tuple As Tuple(Of DataGridView, DataGridView) = TryCast(parameter, Tuple(Of DataGridView, DataGridView))
    29. If tuple IsNot Nothing Then
    30. Dim dgvMonth As DataGridView = tuple.Item1
    31. Dim dgvDaily As DataGridView = tuple.Item2
    32. dgvMonth.AutoGenerateColumns = False
    33. dgvDaily.AutoGenerateColumns = False
    34. End If
    35. End Sub
    36. Public Property CallDgvRemoveHandlerParameterRelayCommand As New ParameterRelayCommand(AddressOf DataGridViewAutoCol)
    37. Public Sub RemoveDataGridViewHandlers(parameter As Object)
    38. Dim tuple As Tuple(Of DataGridView, DataGridView) = TryCast(parameter, Tuple(Of DataGridView, DataGridView))
    39. If tuple IsNot Nothing Then
    40. Dim dgvMonth As DataGridView = tuple.Item1
    41. Dim dgvDaily As DataGridView = tuple.Item2
    42. RemoveHandler dgvMonth.CellFormatting, AddressOf CellFormattingMonthly
    43. RemoveHandler dgvDaily.CellFormatting, AddressOf CellFormattingDaily
    44. End If
    45. End Sub
    46. 'usw... weitere Formatierungen für die DGVs

    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:

    Neu

    Was ist das für eine gezeigte Datei? Ist das eine Partial-Forms-Datei? Wozu gehört sie?

    Amelie schrieb:

    Auszug aus dem "ViewModel"
    Ehh … dass das ViewModel garnixnixnix mit irgendwelchen Controls machen soll, ist Dir schon noch in Erinnerung, oder?


    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.

    Neu

    dass das ViewModel garnixnixnix mit irgendwelchen Controls


    Ja wo soll denn dann das ganze gelumpe hin?
    Auf dem Form (View) darf es nicht.
    Ein (Model) ist es meiner Meinung nach nicht.
    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:

    Neu

    Beschreib mal bitte mit Worten, nicht mit Code, was Du mit den DGVs machen willst. Du weist ihnen Datenquellen zu und sortierst und filterst Daten, richtig?
    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.

    Neu

    @Amelie

    Zu #147

    Sofern man mehrere Parameter hat, kann man auch ein einfaches object nehmen, wobei die gewünsten Übergabeparameter in ein Tupel zusammengefasst werden können.

    Hier ein Beispiel mit entsprechend angepasste RelayCommand
    RelayCommand

    VB.NET-Quellcode

    1. Option Strict On
    2. Option Explicit On
    3. Imports System.Windows.Input
    4. Public Module RelayCommandTest
    5. Public Property RcSample() As New RelayCommand(AddressOf SmapleMethode)
    6. Public Sub Start()
    7. Dim arr1 = New Byte() {0, 1, 2, 3, 4}
    8. Dim arr2 = New Byte() {5, 6, 7, 8, 9}
    9. Dim arrs = {arr1, arr2}
    10. Dim data1 = (5, arrs)
    11. Dim data2 = (arrs, 5)
    12. 'Direkter Test über die Methode
    13. SmapleMethode(5)
    14. SmapleMethode(arr1)
    15. SmapleMethode(arrs)
    16. SmapleMethode(data1)
    17. SmapleMethode(data2)
    18. 'Test über RelayCommand
    19. DirectCast(RcSample, ICommand).Execute(5)
    20. DirectCast(RcSample, ICommand).Execute(arr1)
    21. DirectCast(RcSample, ICommand).Execute(arrs)
    22. DirectCast(RcSample, ICommand).Execute(data1)
    23. DirectCast(RcSample, ICommand).Execute(data2)
    24. End Sub
    25. Private Sub SmapleMethode(input As Object)
    26. Select Case input.GetType
    27. Case GetType(Int32)
    28. Dim data = DirectCast(input, Int32)
    29. Case GetType(Byte())
    30. Dim data = DirectCast(input, Byte())
    31. Case GetType(Byte()())
    32. Dim data = DirectCast(input, Byte()())
    33. Case GetType((Int32, Byte()()))
    34. Dim data = DirectCast(input, (Int32, Byte()()))
    35. Case GetType((Byte()(), Int32))
    36. Dim data = DirectCast(input, (Byte()(), Int32))
    37. Case Else : Throw New Exception
    38. End Select
    39. End Sub
    40. End Module
    41. Public Class RelayCommand
    42. Implements ICommand
    43. Private ReadOnly MCommandAction As Action(Of Object)
    44. Private ReadOnly MCanExecuteCommandAction As Func(Of Object, Boolean)
    45. Public Event CanExecuteChanged As EventHandler Implements ICommand.CanExecuteChanged
    46. Public Sub Execute(parameter As Object) Implements ICommand.Execute
    47. Me.MCommandAction(parameter)
    48. End Sub
    49. Public Function CanExecute(parameter As Object) As Boolean Implements ICommand.CanExecute
    50. Return Me.MCanExecuteCommandAction Is Nothing OrElse Me.MCanExecuteCommandAction(parameter)
    51. End Function
    52. Public Sub NotifyCanExecuteChanged()
    53. RaiseEvent CanExecuteChanged(Me, EventArgs.Empty)
    54. End Sub
    55. Public Sub New(command_action As Action(Of Object), Optional can_execute_command_action As Func(Of Object, Boolean) = Nothing)
    56. ArgumentNullException.ThrowIfNull(command_action, NameOf(command_action))
    57. Me.MCommandAction = command_action
    58. Me.MCanExecuteCommandAction = can_execute_command_action
    59. End Sub
    60. End Class

    Neu

    Man muss hier aber auch feststellen, dass ein DGV ja nicht wirklich mit MVVM läuft, das hat ja seine ganz eigene gut funktionierende Bindinghierarchie, die ganz ganz ganz ähnlich zum MVVM-Pattern ist. Hast du nicht unter WinForms extra eine eigene Tabellenansicht gemacht, die MVVM Bindings ordentlich händelt, Vapo?

    Außerdem muss ich immer wieder feststellen, ihr bewegt euch darum ein existierendes Projekt unter MVVM zum laufen zu kriegen.
    Das hat für mich wenig damit zutun MVVM zu verstehen; kann man da nicht was kleines basteln um erstmal das Grundverständnis aufzubauen?
    Also ein Control gehört für mich zum View, weil der User das gucken und anfassen kann.

    Neu

    Da liegst Du richtig, das ist mein DataListPanel, von dem Du ja schon weißt.

    Haudruferzappeltnoch schrieb:

    Also ein Control gehört für mich zum View, weil der User das gucken und anfassen kann.
    Auf jeden Fall. Eine eventuelle Stilbearbeitung ließe sich ebenfalls im View ansiedeln. Aber sobald es um die Datenaufbereitung geht: ViewModel. Die Daten selbst: Model. Aber das ist Dir ja eh schon klar gewesen.

    Ein MVVM-Testprojekt hatte ich schon in einem anderen Thread erstellt. Da aber solch ein Beispiel oft nicht genutzt wird, sondern der eine oder andere doch lieber sein Baby an die Hand nimmt und es entsprechend formen will, versuche ich hier weiterzuhelfen. Aber es wird schwierig, nach Stunden der Bearbeitung ein fremdes Projekt anzuschauen und dann zu sehen, was alles nicht MVVM-konform ist. Daher wären mir kleine Entwicklungsschritte lieber zu sehen. Dass man ein DGV trotzdem in .NET-Fx zumindest halbwegs MVVM-verträglich anschließen kann:

    Einziger Code im Form-CodeBehind: Setzen der BindingSource-DataSource an eine ViewModel-Instanz und ein RelayCommand-Ersatz. Im VM-Code hab ich zwar eine Datengenerierung mit zufälligen Werten, aber das möge man mir verzeihen :rolleyes:
    Dateien
    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.

    Neu

    ​Du weist ihnen Datenquellen zu und sortierst und filterst Daten,


    Was ich mit den DGVs mache.

    Das Model übergibt die Daten ans ViewModel und das dann ans View. Klappt ja auch.
    Dann, siehe Bild, mache ich die ganzen "Formatierungen.

    Einheiten vergeben, Farben zuweisen, Sortierung setzen usw... evtl wollte ich da noch Filter über die Bindingsource mit einbauen (späääääter aber erst!)

    Im Code von #141 hatte ich dafür noch eine separate Klasse:
    ​Private ReadOnly DgvFormater As New DgvFormater()

    Da hatte ich das ganze Zeugs für die DGV Formtierung drin.
    Danach bin ich wieder unsicher geworden, ob das dann noch dem "MvvM" entspricht und habe alles so umgebaut, das diese Klasse wegfällt und somit der Code Behind eben noch weniger wird.
    Result: Der Code von heute.
    Bilder
    • app-a.jpg

      306,75 kB, 945×381, 11 mal angesehen
    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:

    Neu

    Farben im DGV -> Aufgabe des Views. Das DGV ist ein Control. Das Control wird vom Aussehen her manipuliert. Das ist GUI-Arbeit, also in View, will heißen z.B. in die Form-Klasse damit.

    Daten sortieren -> Aufgabe des ViewModels. Die Daten werden dort aufgearbeitet, aber wer und warum die sortierten Daten anfordert und was damit passieren soll, ist nicht für das ViewModel interessant. Es führt nur den Befehl aus, die Daten zu sortieren und meldet das, wenn es damit fertig ist.

    Einheiten vergeben: Es wäre vielleicht einfacher, dies in die Spaltenköpfe des DGVs zu schreiben, aber das geht auch anders, wenn Du es in jeder Zelle haben willst. Du kannst das Zellenformat vorab im Designer festlegen:



    Ergebnis:


    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.

    Neu

    @VaporiZed
    Ok, was ich da sehe, ist DGV BindingSource BindingSource Viewmodel.
    Und sonst wäre es DGV BindingSource DataSet
    Was bei dir für die Bindingsource das Model ist, sind für die klassischen BindingSources die DataRow-Klassen. Das DataSet mit seinen Tables ist dann schon das Viewmodel.

    Also das ist der Punkt den EDR glaub auch mal hatte mit seinem DDD. Wenn ich DataSet habe, warum nicht nutzen?
    Das ist das einzige was ich in MVVM vermisse, das man sein Model wirklich modellieren kann. Dank DataSet-Designer. (Am Ende entwerfe ich dort die DataRow-Klasse, auch wenn oben DataTable drübersteht)
    Auf der anderen Seite dort wo ich auf DataSet verzichten muss, muss ich auf auf BindingSources verzichten.

    Also ich hoffe du verstehst wie ich das meine, wenn ich sage ich sehe die Sinnhaftigkeit nicht ganz dahinter, das man einen Teil gegen etwas austauscht, was am Ende dasselbe tun soll.

    Neu

    Ich werde niemanden von DDD (Domain "DataSet" Driven Development) abhalten. Aber MVVM ist m.E. dafür da, eine grundsätzlich GUI-unabhängige App zu entwickeln. Das wäre auch mein nächster Vorschlag @Amelie gewesen, ihr VM auf GUI-Unabhängigkeit zu prüfen: Erstellung eines Konsolenprojektes innerhalb der Projektmappe und dieses als Startprojekt festlegen und dort die Daten mithilfe des ViewModels anzeigen zu lassen. Wenn das klappt, scheint erste GUI-Unabhängigkeit zu bestehen.
    Ein tDS-Support schließt Mikrosoft m.E. für zukünftige .NET-Entwicklungen aus. Und ne WPF-Oberfläche an eine »DDD«-App ranzuhängen - na danke. Denn das scheint mir auch ein Wunschziel von Microsoft zu sein: Brückentechnologie auf den Weg weg von WinForms. Ja, Totgesagte leben länger. Aber tDS wird wohl früher sterben als WinForms.
    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.

    Neu

    Meinst Du, notfalls das tDS nicht auf dem GUI nutzen, sondern die GUI-Anbindung tDS-unabhängig machen? Also das tDS nur als Datenverwaltung verwenden? Das würde das dann tDS zu Model und ViewModel machen, oder? Was auch keine Schichtentrennung wäre. Model soll VM nicht kennen, VM soll View nicht kennen. Welche Rolle würde dann das tDS einnehmen?
    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.

    Neu

    VaporiZed schrieb:

    Aber tDS wird wohl früher sterben als WinForms.
    Ich denke, die werden gemeinsam untergegangen gemacht.
    Aber ich hab schon Ersatz angefangen zu stricken: Ein paar generische Klassen, die man in einen relationalen Zusammenhang setzen kann. Und das Ding kann man auch auf Platte speichern.
    Und mit TextTemplates kann ich diese Klassen generieren aus einem Edmx-Designer heraus.
    Es kann halt einiges noch nicht, was tDs kann, deshalb liegtes erstmal rum.