VBP TestingSolution - MVVM Aufbau

  • WPF

Es gibt 52 Antworten in diesem Thema. Der letzte Beitrag () ist von MichaHo.

    Hallo,
    Erstmal Vielen Dank an @florian03 für das Lastenheft...
    Ich habe heute mal Services hinzugefügt.
    Erst ein AppWindow im ViewProjekt erstellt, dann die Service Interfaces (momentan nur das IWindowService) hinzugefügt.
    Im App Projekt dann den WindowService und den ServiceInjector hinzugefügt.
    Bis hierher ist soweit alles verständlich und funktioniert auch.
    Was mir nicht ganz klar ist und wo ich beim Stöbern im WPF-Projekt nicht dahinter gestiegen bin.
    Im AppWindow ist ein ContentPresenter, dessen Content über Content="{Binding}" verfügt.
    In der App.xaml hab ich 2 DataTemplates angelegt.
    Das Fenster wird geöffnet und setzt den DatenContext auf den MainWorkspace, aber im Fenster wird nichts angezeigt.
    Wie sagen wir nun der App, das der aktuelle Content der MainWorkspace bzw. dessen MainControl ist??
    "Hier könnte Ihre Werbung stehen..."
    Habs raus bekommen....
    Im Constructor des AppWindow musste ich einen Handler hinzufügen um die Methode AppWindow_Loaded aufzurufen, denn dort wird der Context gesetzt.

    in VB wird dies durch das Handels Me.Loaded erwirkt, in C# muss da ein Handler für hergenommen werden. (Denke ich, weis es nicht genau)

    Nun klappt es ...
    "Hier könnte Ihre Werbung stehen..."
    Ist eine möglichkeit.
    Eine andere wäre es das Anwendungsframework abzuschalten und in der App.cs pber das WindowService das erste Fenster aufzurufen. Dann wird auch das DataTemplate verwendet.

    Das Lastenheft schau ich am Wochenende durch, war diese Woche viel im stress.

    Frage? Soll alles ein einer XML gespeichert werden oder soll es je Modelklasse und Instanz XMLs geben. Ich denke es werden so wenig Datensätze das eine große XML fast reicht. Was sagt Ihr?
    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 Sascha,
    ich rufe das Fenster über den Service auf und das datatemplate passt auch, beim debuggen hab ich halt festgestellt das er garnicht die die Methode rein springt.
    VB bewirkt das durch Handels Me.Loaded in c# muss man den Handler vorher setzen, sonst springt er da nicht rein.

    Für den Anfang reicht ein Gesamt XML, später muss es definitiv ins Web verlegt werden.
    "Hier könnte Ihre Werbung stehen..."
    Das ist aber nur weil das Anwendungframework das MainWindow öffnet und nucht ein Window über unser Service.

    Aber ich schau es mir wie gesagt übers Wochenende mal an, da hab ich etwas Luft.

    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 Leute

    Ich bin nun dazu gekommen mir das Projekt zum ist-Stand vor 5 Minuten anzusehen und sehe das soweit eigendlich alles passt.

    MichaHo schrieb:

    später muss es definitiv ins Web verlegt werden.

    Wenn ich hier das "definitiv" lese dann würde ich aber fast wirklich sagen das wir das gleich einbauen. Ich dachte ja das es ein reines "Schulungsprojekt" wird aber das hört sich so an als wenn es tatsächlich für den Produktiveinsatz verwendet werden soll. Wenn dem so ist würde ich aber fast gleich ne WebAPI dafür bauen, die Frage ist ob das hier dann nicht den Rahmen sprengt. Oder wir lassen es für XML und @MichaHo baut es sich dann selbst um.
    Jetzt weis ich warum du das generische Repository drinnen haben wolltest. Damit du dann ohne viel Aufwand diesen Layer tauschen kannst.

    Da lasse ich dir nun die Entscheidung wie du es haben willst. a.) Rein auf XML und du baust es später um b.) gleich mit WebAPI oder c.) generisches Repository mit XML damit es später leichter austauschbar ist.

    So, kommen wir zum ist-Stand.
    Da wir einen Login haben werden würde ich diesen fast als Dialog öffnen bevor das Hauptfenster geladen wird. Das vereinfacht einiges und ist für die meißten User intuitiver. Weiters kann man dann gleich den Username z.b. in einer Statusbar zeigen und z.b. Menuitems welche den User nicht interessieren weil er die Rechte nicht hat einfach erst garnicht erstellen. So nur mein Vorschlag, aber wir machen es wie ihr wollt.
    Auf jeden Fall würde ich damit Anfangen.

    In diesem Sinne: Schreib bitte mal welche Funktionen der Login genau haben soll und mach mal ein ViewModel dafür, das puscht du auf GitHub und wir besprechen es hier.

    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,
    kann mich morgen dran setzen, hab etwas Luft morgen.
    ich würde gerne das Generic Repo drinn lassen.
    Da es öffentlich auf GitHub liegt sollte es am Ende doch Produktiv eingesetzt werden können. Im Ersten Step allerdings reicht ein lokales xml, die WebApi kann ich dann später dazu bauen, oder auch andere interessierte.
    Dialog....Hmmm...ja....hmmmm, hatte ich schon mal erwähnt das ich Dialoge nicht sooooo mag. Können wir aber gerne machen. Btw. Den Usernamen bekomm ich auch im LoginViewModel und kann ihn beim switchen vom View dann auch in einer Statusbar anzeigen. Aber wir machen einfach mal nen Dialog, da kann man ja schön zeigen wie Services funktionieren.
    "Hier könnte Ihre Werbung stehen..."
    Ja, Dialog kann man es ja fast nicht nennen da es ja nicht über ein anderes Fenster aufgeht sondern alleinstehend. Loggt man sich erfolgreich ein geht das Hauptfenster auf und wenn nicht (Abbruch) geht die ganze App zu. Also ist Dialog vieleicht gar nicht so treffend. Ist aber nicht umsonst fast in jeder App so.

    Mach mal ein ViewModel für einen Login und dann machen wir die BL und das Repo dazu.

    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. ##

    Genau, dies und vieles mehr. Einen Login finde ich immer eine gute Übung da hier sehr viel bereits enthalten sein sollte.

    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

    So, hatte kurz Zeit.

    Zum einen beschränke ich mich im Moment jetzt rein nur mal an das ViewModel und keine View. Das ist das was erstmal fertig sein muss. Damit das ViewModel fertig gemacht werden kann muss ja sowieso auch die Logik in die BL implementiert werden wie du ja gesehen hast.

    * Ich habe aus der ViewModelBase zwei Interfaces rausgenommen. IDataErrorInfo und IViewModelValidation.
    Der Grund: Nicht jedes ViewModel muss validiert werden. Es wird genug ViewModels geben welche das nicht benötigen werden, ist also unnötig. Und da man in jedem ViewModel in welchem man es benötigt hier sowieso eigenen Code schreiben muss (Methode also überschreiben müsste) macht es aus meiner Sicht mehr Sinn das Interface einfach ins jeweilige ViewModel herein zu holen wenn man es benötigt.

    * OK, das Property "LoginIsRunning" habe ich entfernt. Dafür haben wir das "VmIsBusy" in der Basisklasse.

    * Ich habe also die Interfaces in die LoginViewModel Klasse implementiert und dort auch den Code reingepackt. und auch ein paar Zeilen geändert, manche einfach nur um es besser Testbar zu machen, und da kommen wir zum nächsten punkt.

    * Ich habe UnitTests hinzugefügt. Alle Tests ausser einem ("CanLoginIfDataIsCorrect") laufen durch und sind grün. Der eine welcher "Rot" ist kann auch nicht durchlaufen. Es gibt noch keine Logic für einen Login. Diese sollte in die BL wandern. Im realen App-Leben kommen die Daten aus z.b. einer XML oder einer DB in welcher man eine Liste von Usern gespeichert hat. In dieser Anwendung wird es zum ersten jetzt mal eine XML sein.
    Da du später auf eine WebApi umsteigen willst kannst du nun doch (das wusste ich am Anfang ja nicht) ein Repository hinzufügen. Obs nun ein generisches ist oder ein nicht-generisches überlasse ich dir.
    Nun ist das Ziel das das ViewModel einfach abfragen kann ob die Kombi aus Username und Passwort korrekt sind. Aber..... das ganze soll ja Testbar sein. Und das ist die Hausaufgabe die ich jetzt mitgebe, denn genau um das geht es ja bei MVVM auch.

    Als kleinen Tipp auf den Weg. UnitTests müssen immer (in jeder Umgebung, also Zuhause, auf nem Server, am Mond und in Mordor) ausfüshrbar sein. Sie müssen schnell und sicher sein.
    Das bedeutet das man keine Abhängigkeiten haben darf wie z.b. eine XML auf der Platte. Man benötigt also einen "Fake" oder auch "Mock" genannt.

    Und los geht...

    PS: Hier die änderungen

    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. ##