Support, Anregungen, Wünsche zur Tutorialreihe <WPF lernen/>

  • WPF MVVM

Es gibt 448 Antworten in diesem Thema. Der letzte Beitrag () ist von Nofear23m.

    MichaHo schrieb:

    keine Schande
    Ansichtssache.
    NoFear (und mit ihm eine Menge annerer MVVM-Spezialisten) sehen das anners als ich.

    Zu (meinem) Glück ficht mich das nicht sooo an, wenn jmd findet, ich programmiere schändlich ;)
    Zu meinem Unglück bin ich mit meiner Ansicht deutlich in der Minderheit - tatsächlich kann ich derzeit kaum jmd benennen, der meine Ansicht teilt, ausser dem einen oder anneren, dem ich selbst Wpf auseinandergestzt habe.
    Jdfs. in Foren wird man schnell niedergebrüllt, wenn man sich defätistisch äussert - hier halte ich wiederum NoFear sehr zugute, dasser imo wirklich ein Wpf-Spezi ist, und daher derlei Gebrüll net nötig hat.
    Hatte meinen letzten Post unabsichtlich zu früh abgesandt, bitte nochmals ansehen falls jemand zu früh drann war.

    ErfinderDesRades schrieb:

    Jdfs. in Foren wird man schnell niedergebrüllt, wenn man sich defätistisch äussert - hier halte ich wiederum NoFear sehr zugute, dasser imo wirklich ein Wpf-Spezi ist, und daher derlei Gebrüll net nötig hat.

    Selbst wenn ich mal brülle, meine ich es ja nicht so. Ich finde deine ansicht ja nicht Falsch. Bitte nicht falsch verstehend, sie hat ja was wahres und auch teilweise gutes. Ich finde nur falsch zu sagen es wäre MVVM. Es ist MVM wenn man so will. Genau (!!) MVM würde es treffen denke ich. ODer?


    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    @Nofear23m Danke für Deinen Post... so langsam kapier ich es auch...
    Das mit den eignenen Projekten in MVVM hab ich soweit schon umgebastelt.
    Gerade die ModelBase, NotifyBase, ViewModelBase, RelayCommand brauch ich ja in jedem Projekt, daher hab ich das soweit ausgelagert...
    Was mir jetzt allerdings beim AddNewNote via ViewModel zu schaffen macht ist, das ich ja dann im ShowNotes View das Fenster des AddNewNote deklariere und dort schon den Context mitgebe, der im Moment ja das Model ist. Stelle ich das auf ein ViewModel um knallt es beim Speichern da das ViewModel ja nicht zu einer bestehenden Observable Collection hinzugefügt werden kann, sondern nur ein Model...
    Also wie bekomme ich das Note aus dem ViewModel dann gespeichert?

    VB.NET-Quellcode

    1. Private Sub AddNewCategoryCommand_Execute(obj As Object)
    2. Dim dialog = New AddCategoryWindow With {
    3. .Owner = Me,
    4. .DataContext = New Model.Category
    5. }
    6. If dialog.ShowDialog Then
    7. CategoryList.Add(CType(dialog.DataContext, Model.Category))
    8. End If
    9. End Sub

    Hier ist ja das Model gebunden, wenn ich hier aber ein ViewModel binde?
    "Hier könnte Ihre Werbung stehen..."

    MichaHo schrieb:

    Gerade die ModelBase, NotifyBase, ViewModelBase, RelayCommand brauch ich ja in jedem Projekt, daher hab ich das soweit ausgelagert...

    Falsch, ViewModelBase und RelayCommand benötigst du dann nur noch im ViewModel-Projekt. ModelBase im Model.

    Aber wie gesagt, so einfach ist es dann nicht getan mit MVVM, da muss schon noch mehr her.
    Gerne kann ich eine WPFNotes MVVM Version mit korrektem und trotzdem übersichtlichem MVVM maschen wenn hier interesse besteht, nur damit das ein für alle mal vom Tisch ist. Ich greife allerdings wirklich ungern so weit vor, da brauche ich ja dann nix mehr im Tutorial machen =O

    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    Mal ein wenig offtopic:
    Leute ihr seit zu schnell, ich komme mit dem lernen nicht hinterher. Ich war auch schon am überlegen es gleich mit mvvm zu probieren. Nach ein wenig lesen habe ich es gelassen, mir fehlt viel zu viel Wissen um es nur gedanklich richtig sortiert zu bekommen.
    Muss jetzt erstmal die ganzen Tutorials nacharbeiten, und wenn online den Livestream nachholen.
    Danke für deine Super Arbeit und vor allem deine Geduld mit uns.
    Rechtschreibfehler betonen den künstlerischen Charakter des Autors.
    Hallo Akanel. Das kann ich voll verstehen. Deshalb meinte ich das man es Schritt für Schritt machen muss. Beispielsweise Binding muss sitzen. Interfaces, Basisklassen, Properties das muss alles aus dem FF gehen.

    Deshalb mach ich das Tutorial Schritt für Schritt. Das ist wichtig sonst verliert man leicht die Lust.

    Das Video war sofort nach dem Stream online. Auf wunsch kann ich wegen den technischen Problemen das Original von meiner Platte hochladen, nur muss ich den Lautstärkepegel ab der 10. Minute oder so nach oben Schrauben.

    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    um dem Tut vorzugreifen :evil:

    ErfinderDesRades schrieb:

    Und wenn man da nicht eine ausgefeilte Strategie verfolgt, kommt man da bei Zufügungen/Löschungen auch an Grenzen des Machbaren.
    Zum Glück verfügt NoFear über eine geeignete Strategie, indem er glaub ListCollectionView Events abonniert, und so Zufügungen/Löschungen im Viewmodel gleich überträgt ins Model.

    Hier ist eine Solution angehängt, wo angugge kann, wassich als "NoFears Strategie" bezeichne, um Viewmodel/Model - Zufügungen/Löschungen zu handeln.
    Bisserl weiter habich eine Verallgemeinerung vorgestellt, mit der man dabei einiges an BoilerPlate einsparen kann: Bindung nach Entity Model first aktualisiert Daten nicht!
    Neues Kapitel Online!!!

    2.1.4.5 Binding über DataTemplates

    Viel Spaß damit!!


    Wegen vorheriger Antwort von EDR:
    Wobei ich sagen muss das natürlich die Variante von @ErfinderDesRades nicht zu verachten ist. In kleineren Projekten wie in dem WpfNotes habe ich ja auch INotifyPropertyChanged in das Model mit reingenommen und so viel wie er es ausdrücken würde "BoilerPlate Code" verhindert. Da dies kein MVVM Projekt war ist das auch völlig in Ordnung und sicher praktikabel. Da hat EDR definitiv Recht.
    Auch sehe ich ein das es wirklich wirkt wie wenn man viel "nicht notwendigen" Code in einer MVVM gestützten Anwendung hätte, in der Praxis (bei echten und Benutzfreundlichen Anwendungen) ist dies allerdings nicht dar Fall, hier muss für fast jedes View ein ViewModel her, alleine schon wegen den Commands, auch wenn mir die Eigenschaften des Models genügen, wie binde ich gewisse Ereignisse ohne einer ViewModel-Klasse? Das ist der Punkt.

    Aber klar, EDR versucht den Ansatz mit dem geringsten Codeaufwand zu verfolgen, völlig verständlich. Man kommt aber leider (!!) früher oder später zum Entschluss das dies nicht so einfach möglich ist.

    Abschliessend noch: MVVM ist nicht immer brauchbar!! Kleinere Projekte können durch den Einsatz von MVVM schnell sterben. Man muss sich gut überlegen ob sich MVVM auszahlt oder nicht. Gerade am Anfang wo man sich noch etwas schwer tut.

    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    Sorry, dassich noch einen Durchlauf ablassen muss - ich sehs einfach anders.
    Mein Begriff von MVVM ist flexibel. Also auch wenn Model und ViewModel nicht getrennt sind, nenne ich das dennoch MVVM.
    Model und Viewmodel sind ja da, nur evtl. nicht ausdifferenziert, solange das nicht nötig ist.
    Damit ist gleichzeitig gesagt, dass sofort ausdifferenziert wird, sobald die Differenzierung Vorteile erbringt (aber halt nicht unbedingt früher).

    Ene Wpf-Anwendung nenne ich MVVM, wenns unabhängige Klassen gibt, welche per Databinding mit der View interagieren. Weil das ist doch ein Viewmodel. Und wenns gleichzeitig auch ein Model sein kann sehe ich da kein Problem.
    Und so flexibel verstanden kann MVVM nahezu frei von BoilerPlate sein, und ist ausserdem durchaus immer brauchbar, und davon profitieren auch kleine Projekte.

    Ich rate jedem dringend ab, olle CodeBehind aus der Klamottenkiste zu holen, mit Begründung "Projekt ist ja nur klein". Solches wäre natürlich auch in meim Verständnis kein MVVM, wäre qualitativ minderwertig weil schlecht wartbar, kaum erweiterbar, umständlich und eine vergebene Chance.
    (Wobei's natürlich Anwendungen gibt, die garnet gewartet oder gar erweitert werden sollen - da ists nur womöglich dennoch umständlicher als MVVM, und eine vergebene Chance)
    Hallo @ErfinderDesRades

    Ich gebe dir ja durchaus recht. Man kann es natürlich so sehen. Ich verstehe deinen Standpunkt und du hast ja auch recht. Sicher kann es "hilfreich" sein vom View eine Referenz auf das Model zu haben.
    Wichtig ist mir hierbei nur immer das man in einem Forum wo es darum geht korrektes Wissen weiter zu geben, zu bedenken das man acht gibt was man rüberbringt. Und da dieses vorgehen das MVVM nun mal verletzt ist es nun mal so das ich das hier nie laut sagen würde.
    Sehen wir auf WIKI fällt einem gleich folgender Satz auf:
    Das MVVM nutzt die funktionale Trennung des MVC-Musters von Model und View. Zum Erreichen einer losen Kopplung zwischen diesen Komponenten

    oder
    Views können von reinen UI-Designern gestaltet werden während Entwickler unabhängig davon die Models und ViewModels implementieren.


    Dies wird nicht mehr Erreicht sobald im View eine Referenz auf das Model besteht. Fakto ist es eine verletzung des MVVM Pattern. Nenne es MVVM Light wenn du willst aber mit einer Beschreibung zu MVVM bin ich hier immer vorsichtig.
    Wir haben heute sooo viele Möglichkeiten Daten zu bekommen. Datenbank, Webservice, TCP/IP, Sharepoint, Azure, XML und vermutlich noch hundert andere.
    Wenn gleich es früher als Entwickler weniger notwendig war hier eine Austauschbarkeit in erwegung zu ziehen ist es heute umso wichtiger. Ich habe es schon öfters gesehen das sich sowohl die Art wie Daten geholt werden als auch die Daten selbst geändert hatten da sich Strukturen im Unternehmen oder einfach die Technologie geändert hatte.
    Auf genau sowas zielt MVVM. Hier kann sich das Model ändern und/oder die Geschäftlogik ändern ohne das ich das View auch gleich mit austauschen muss.

    Mir ist klar das dies bei vielen Programmen und kleineren Projekten eine untergeordnete Rolle spielt, dennoch stellt es eine verletzung dar. Ist leider so, ich habe das Pattern nicht definiert. Es hat eine Definition, und diese lässt in diesem Bereich keinen spielraum. Is Fakt.

    Nochmal: Ich gebe dir VOLL Recht und man kann das machen. Jeder kann das Model mit ins View nehmen, eine verletzung ist es dennoch. Sehen wir uns nur die erste Grafik vom Wiki Artikel an sehen wir das sofort.
    Wir könnten uns ja darauf einigen das wir es MVVM Light nennen aber MVVM ist es ab dann nicht mehr. Es geht mir jetzt auf keinen Fall darum wer da jetzt Recht hat, um Gottes willen. Ich will nur hier im Forum nichts sagen von dem ich weis das es nicht wirklich stimmen würde und andere damit verwirren weil sie sicher wo anders dann was anderes lesen werden.
    Ich weis genau das du dich mit dem Pattern auskennst und ich weis das du in Sachen programmieren sicher mehr auf dem Kasten hast als ich es habe, mir geht es lediglich um die Definition von MVVM. Und diese kenne ich. Ich habe mit fast ein Jahr damit beschäftigt um dieses wirklich voll zu verstehen und einen Weg zu finden komfortabel damit zu Arbeiten, auch weil es in diesem Bereich im Netz sicher 200 verschiedene Ansätze zur umsetzung gibt.


    Schöne Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    Hallo @Nofear23m ich bin am WE mal weiter im Tutorial gegangen und auf die Templates gestoßen.
    Dort erklärst Du das HierachialDataTemplate.
    Ich wollte dies gerne in meinem Proejekt einbauen, damit ich im Hauptfenster bisschen besser Koordinieren kann.
    Nun stellt sich mein Problem, das ich über das Binding nicht an die Childs dran komme.

    Ich habe im ViewModel eine AvailableInstructionView, die alle Instructions gefilter nach der ProductionLine.
    Das klappt wunderbar.
    Nun wollte ich von dieser AvailableInstructionView gerne die MainSteps und die ChildSteps haben.
    Leider Komme ich mit

    XML-Quellcode

    1. AvailableInstructionsView.MainSteps
    oder

    XML-Quellcode

    1. AvailableInstructionView.CurrentItem.MainSteps

    nicht an die ChildElemente...
    Hast Du nen Tip, wie ich den TreeView dahingehend richtig befülle?
    Brauch ich eine Hilfs Methode um die Childs da zu richtig zuzuweisen?
    "Hier könnte Ihre Werbung stehen..."
    Hallo @MichaHo

    Da hast du leider die HirachialDataTemplate ein wenig falsch verstanden, was allerdings auch leicht passieren kann.
    Diese sind dafür da wenn es theoretisch Endlos viele Ebenen unterstützen musst.

    Also wenn z.b. deine ChildSteps wieder ein Propertie List(Of ChildStep) hätte. Denn dann könnte man Endlos lange zu jedem Step wieder Steps hinzufügen.

    Das ist aber bei dir nicht der Fall soweit ich das in erinnerung habe. Du hast MainStep, darin hast du die Eigenschaft ChildSteps als Auflistung von Typ ChildStep und fertig.

    Also benötigst du nur zwei Klassen auf welche du Binden kannst.
    Du hast ja sagen wir mal in einem NotesViewModel ein Property AvailableInstructionView mit allen Instructions wie du oben beschrieben hast.
    Innerhalb von Instrctions gibt es die eigenschaft MainSteps, wieder als Auflistung.
    Du schreibt eh richtig das du auf das selektierte MainStep zugreifst mit: AvailableInstructionView.CurrentItem.MainSteps
    Und im MainStepViewModel hast du auch eine ICollectionView auf welche du zugreifen kannst. z.b. AviableMainSteps.CurrentItem

    Was allerdings NUR geht WENN nicht direkt das Model verwendet wird sondern eine ViewModel-Klasse, und genau da sind wir wieder da wo EDR und ich die letzten Posts über diskutieren.
    So, und nun sind wir da wo wir nicht hin wollten, das du vermutlich verwirrt bist wie du es jetzt genau umschreiben musst. Und das meine ich die ganze Zeit. Man soll NICHT suggerieren das es in Ordnung ist das Model an die View zu Binden.

    MainStep ist vermutlich wie ChildStep direkt eine Modelklasse, und nun stehst du da und hast keine ICollectionViewSource darin, was ja in einem Model auch nicht viel zu suchen hat.
    Nun musst du für jede Modelklasse wo du eine ICollectionView benötigst eine ViewModel Klasse dazwischen schieben. Das ist leider so, weil du nun an dem Punkt bist wo du nicht mehr so einfach (möglich wäre auch das, das will ich aber ungern lehren) mit den reinen Modelklassen auskommst weil der View nun bereits "höhere Anspüche stellt" als das Model alleine erfülen kann.

    Ist schwer zu erklären, ich hoffe ich konnte es etwas rüberbringen.
    Ich finde es sehr Lobenswert das du hier versucht so viel zu lernen und das hat meinen allerhöchsten Respekt, Ehrlich!! Aber ich bin fast der Meinung das du hier schneller unterwegs bist als die anderen welche das Tutorial verfolgen, was ja gut ist! die Frage ist nur ob wir das vieleicht in einem eigenen Thread behandeln sollten solange ich mit dem Tutorial noch nicht so weit bin. Ich kann mit dir gemeinsam gerne die Applikation aufbauen und dir zeigen wie ein richtiger Strukturierter Aufbau funktioniert damit du dich rein auf diesen konzentrieren kannst, hier denke ich verschrecken wir vieleicht ein paar Leute da ja sowieso in den Köpfen dieses "WPF ist so kompliziert" drinnen ist.

    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    Hallo @Nofear23m
    Hab mir schon gedacht das ich da ein View für brauche.
    Habe in meinem Projekt auch die ganzen Workspaces erstmal durch ViewModels ersetzt und binde auch an diese. (Außer beim Erstellen einer ProductionLine, da hab ich das Model direkt an die View gebunden).
    Im Xaml kann ich im HierachialDataTemplate wohl nicht direkt an

    XML-Quellcode

    1. AvailableInstructionView.CurrentItem.MainSteps
    binden. Daher benötige ich dafür eine iViwCollection -> hab ich verstanden.
    Wir können das gerne auslagern...
    Ich baue mir jetzt erstmal die ganzen ViewModels mit den Views die ich benötige, erstelle dann einen neuen Thread und häänge dort den aktuellen Stand dran.. OK?

    EDIT: Achso, im Grunde möchte ich im TreeView die Instructions mit den MainSteps und den ChildSteps anzeigen.
    "Hier könnte Ihre Werbung stehen..."

    MichaHo schrieb:

    EDIT: Achso, im Grunde möchte ich im TreeView die Instructions mit den MainSteps und den ChildSteps anzeigen.

    OK, das sollte so dann auch möglich sein. Aber... in einem TreeView? Ist das so geeignet dafür. Naja, egal eigendlich, das kann man so machen.
    Am einfachsten wäre es für mich wenn du das Projekt mal hochladen würdest, dann muss ich die Klassenstruktur nicht nachbauen.

    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    Hi,
    das TreeView befindet sich im ucOsiLeft.
    Die Listboxen rechts im ucMainChildSteps sollen dann durch das AddStepWindow ersetzt werden.

    Danke Dir
    Dateien
    "Hier könnte Ihre Werbung stehen..."
    Hallo

    Also, ich habe rein gar nichts im Code geändert, rein in XAML im ucOsiLeft habe ich das Binding der Templates innerhalb des TreeViews korrigiert!

    Hier zum vergleichen:

    XML-Quellcode

    1. <TreeView DataContext="{Binding}" ItemsSource="{Binding AvailableInstructionView}" >
    2. <TreeView.Resources>
    3. <HierarchicalDataTemplate ItemsSource="{Binding MainSteps}" DataType="{x:Type model:Instruction}">
    4. <StackPanel Orientation="Horizontal">
    5. <TextBlock>
    6. <Run Text="{Binding FormularNumber}"/>
    7. <Run Text=" - "/>
    8. <Run Text="{Binding FormularName}"/>
    9. </TextBlock>
    10. </StackPanel>
    11. </HierarchicalDataTemplate>
    12. <HierarchicalDataTemplate ItemsSource="{Binding ChildSteps}" DataType="{x:Type model:MainStep}">
    13. <StackPanel Orientation="Horizontal">
    14. <TextBlock>
    15. <Run Text="{Binding StepNumber}"/>
    16. <Run Text=" - "/>
    17. <Run Text="{Binding StepText}"/>
    18. </TextBlock>
    19. </StackPanel>
    20. </HierarchicalDataTemplate>
    21. <HierarchicalDataTemplate ItemsSource="{Binding ChildSteps}" DataType="{x:Type model:ChildStep}">
    22. <StackPanel Orientation="Horizontal">
    23. <TextBlock>
    24. <Run Text="{Binding StepNumber}"/>
    25. <Run Text=" - "/>
    26. <Run Text="{Binding StepText}"/>
    27. </TextBlock>
    28. </StackPanel>
    29. </HierarchicalDataTemplate>
    30. </TreeView.Resources>
    31. </TreeView>


    Grüße
    Sascha

    PS: War das das was du meintest???

    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    Hi @Nofear23m nicht ganz.
    Im TreeView soll quasi die Instruction als oberste ebene angezeigt werden.
    Darunter die dazugehörigen MainSteps und darunter die dazugehörigen ChildSteps.
    Da hört die Hierachie dann auch schon auf, denn ChildStep kann niemals weitere ChildSteps haben...
    Ich versteh glaub die Hierachie des Treeview noch nicht ganz.
    Die Source des TreeView (der DataContext) ist ja die InstructionView, darin sollten ja alle Instructions samt Main und ChilödSteps sein.
    Problem hab ich mit der ersten Hierachie... die Instructions werden mir nur im Designer angezeigt, zur Lauifzeit nicht mehr...
    "Hier könnte Ihre Werbung stehen..."
    Tuts doch nun.
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    Häää?? bei mir nicht... hab genau dein TreeView xaml eingebaut, wird nix angezeigt

    Hab die XML mal gelöscht und nun geht es...
    Bin halt etwas verwirrt, weil in der obersten Ebene auf MainSteps gebunden wird, aber Instructions angezeigt:

    XML-Quellcode

    1. <HierarchicalDataTemplate ItemsSource="{Binding MainSteps}" DataType="{x:Type model:Instruction}">
    2. <StackPanel Orientation="Horizontal">
    3. <TextBlock>
    4. <Run Text="{Binding FormularNumber}"/>
    5. <Run Text=" - "/>
    6. <Run Text="{Binding FormularName}"/>
    7. </TextBlock>
    8. </StackPanel>
    9. </HierarchicalDataTemplate>

    "Hier könnte Ihre Werbung stehen..."