Code Verbesserung für MVVM

  • WPF

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

    So, jetzt hab ich mir die Artikel alle durchgelesen. Verstanden hab ich es nicht zu 100%.
    Daher hab ich nun mal das Projekt umgebaut.
    Es gibt nun eine MainModel Klasse und eine MainViewModel. Das View muss ich noch basteln...
    Hier die MainModel Klasse:
    Spoiler anzeigen

    C#-Quellcode

    1. class MainModel
    2. {
    3. public double MeasuredValue { get;private set; }
    4. public bool IsValid { get; private set; }
    5. public bool IsConnected { get; private set; }
    6. NetworkStream _NetworkStream;
    7. StreamReader _StreamReader;
    8. TcpClient _TCPClient;
    9. public MainModel() { }
    10. public double GetMeasuredValue(string client)
    11. {
    12. ConnectToServer();
    13. client += Environment.NewLine;
    14. byte[] sendbyte = new ASCIIEncoding().GetBytes(client);
    15. _NetworkStream.Write(sendbyte, 0, sendbyte.Length);
    16. _NetworkStream.Flush();
    17. string result = null;
    18. result = _StreamReader.ReadLine();
    19. DisconnectFromServer();
    20. string tempstring = null;
    21. string[] temparray = result.Split(';');
    22. for (int i = 0; i < temparray.Length - 1;)
    23. {
    24. if (temparray[i].StartsWith("valid"))
    25. if (temparray[i].Substring(6).Equals("1"))
    26. IsValid = true;
    27. if (temparray[i].StartsWith("value"))
    28. tempstring = temparray[i].Substring(6);
    29. }
    30. NumberFormatInfo numberformat = new NumberFormatInfo();
    31. numberformat.NumberDecimalSeparator = ".";
    32. return MeasuredValue = double.Parse(tempstring, numberformat);
    33. }
    34. private void ConnectToServer()
    35. {
    36. _TCPClient = new TcpClient("10.21.89.246", 4000);
    37. _StreamReader = new StreamReader(_TCPClient.GetStream());
    38. _NetworkStream = _TCPClient.GetStream();
    39. _TCPClient.ReceiveTimeout = 2000;
    40. IsConnected = true;
    41. }
    42. private void DisconnectFromServer()
    43. {
    44. _TCPClient.Close();
    45. IsConnected = false;
    46. }
    47. }


    und dazu die MainViewModel:
    Spoiler anzeigen

    C#-Quellcode

    1. class MainViewModel : Class.ViewModelBase
    2. {
    3. //Model kapseln
    4. private Model.MainModel _MainModel;
    5. //Konstruktor
    6. public MainViewModel(Model.MainModel mainmodel)
    7. {
    8. this._MainModel = mainmodel;
    9. }
    10. //Eigenschaften der ModelKlasse 'MainModel' kapseln!!!
    11. public double MeasuredValue
    12. {
    13. get{return this._MainModel.MeasuredValue;
    14. this.OnPropertyChanged("MeasuredValue");}
    15. }
    16. public bool IsValid
    17. {
    18. get { return this._MainModel.IsValid;
    19. this.OnPropertyChanged("IsValid");}
    20. }
    21. public bool IsConnected
    22. {
    23. get { return this._MainModel.IsConnected;
    24. this.OnPropertyChanged("IsConnected"); }
    25. }
    26. private double GetMeasuredValue(string comPort)
    27. {
    28. double measureValue = _MainModel.GetMeasuredValue(comPort);
    29. if (measureValue != 0 && IsValid)
    30. return MeasuredValue;
    31. return 0;
    32. }
    33. }


    nun will/muss ich im View ja 2 MeasuredValue bekommen. (Serverraum und Elektroraum). 2 verschiedene ComPorts.
    Muss ich da nun 2 Methoden machen und in 2 unterschiedliche Variablen rein packen?
    Oder besser eine List<of String> (observable hab ich noch nicht geschafft anzugucken).
    Wenn das View startet, sollen die Werte abgeholt werden und dann alle 5 Minuten aktualisiert werden.
    @ErfinderDesRades das mit deinen Helpers und den Testdaten war mir zu hoch :)
    Im Grunde gibt es momentan 2 ComPorts, die abgefragt werden müssen pcmeasure.com1.1 und pcmeasure.com3.3 (LAN Port 1 und LAN Port 11).

    EDIT: wobei ich grad sehe, das im MainViewModel bei den beiden Propertys ja keine Setter benötigt werden, also muss die OnPropertyChanged ja in den Getter...
    "Hier könnte Ihre Werbung stehen..."
    Also PropertyChanged im Getter werfen macht keinen Sinn, weil da ja nichts gesetzt wird. Du musst da schon noch einen Setter hinzufügen.
    Außerdem, warum gibst Du das Model explizit im Konstruktor mit? Instanziiere das doch im ViewModel.
    Architektonisch verstehe ich nicht ganz, was Du in Deinem ViewModel machst. Du wirfst da irgendwie Model und ViewModel-Properties wild durcheinander. Der Sinn wäre eigentlich in einer Methode ​GetMeasuredValue die Eigenschaft ​MeasuredValue zu setzen und nicht diese zurückzugeben, nachdem das intern im Model anscheinend gesetzt und somit automatisch in der Property aktualisiert wurde. Außerdem müsstest Du das dann über Commands etc. steuern.

    Für Deinen ComPort habe ich Dir ja bereits die Idee gebracht, dafür eine eigene Klasse zu bauen und diese dann in die Liste bzw. ObservableCollection (besser) zu packen. Die ObservableCollection ist auch nicht viel komplexer und kann syntaktisch genauso verwendet werden. Binden kannst Du ja ohne Probleme an die Eigenschaften der Klasse ​ComPort, sodass diese auch im View angezeigt werden können.
    ​this kannst Du btw weglassen und es sollte wenn ​_mainModel heißen.

    Grüße
    #define for for(int z=0;z<2;++z)for // Have fun!
    Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

    Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:

    MichaHo schrieb:

    Bevor ich daher weiter mache, frag ich nach Eurer Meinung/Erfahrung/Tips.
    Bezüglich dessen, hier noch ein paar Anregungen von mir:

    1.) Versuche zwischen Properties, welche du nach außen greifbar machen willst, und privaten Membervariablen, welche du nur im lokalen Kontext - deiner Klasse - verwenden willst. Es macht bspw keinen Sinn eine private Membervariable, die du nur lokal verwendest, als Property zu kennzeichen (Klasse MConnection).
    2.) Wenn du Sachen, wie IP Adressen oder Hostnamen, welche sich mit .NET Framework Klassen/Strukturen darstellen lassen, verwendest, dann ziehe diese den primitiven Datentypen/selber gemachten Datentypen vor. In deinem Code etwa verwendest du für deinen Server eine Property Host vom Typ String. Hier böte sich eine Property Host vom Type IPAddress an. Warum, dazu komm ich gleich noch.
    3.) Wenn du dein ViewModel mit Testdaten füttern willst, kannst du hergehen und dir im VS Desginer einer neue XAML Datei erzeugen lassen. Dies musst du dann aber über die Eigenschaften als DesignData kennzeichen. Dann nur noch in die Resourcen des Views einbinden und du hast Testdaten in der Vorschau (kannst z.B. das Aussehen der Daten in einer ListView testen/dir ansehen). Hierzu brauchst du aber parameterlose Konstruktoren. Um dies zu erreichen, empfehle ich dir bei jeder Klasse (oder zumindest bei der allerobersten Basisklasse, welche du im ViewModel verwendest - in deinem Fall MConnection eben einen Default-Konstruktor einzubauen, welche die Properties auf default Werte und eine Property, welche anzeigt, ob die Datenquelle verwendet werden kann, entsprechend setzt. Die kann dann meinetwegen IsUsable heißen und vom Typ bool sein. Ich hab deswegen in Punkt 2 geschrieben: Framework Datentypen verwenden, da du hier z.B als Defaultwert als IP Adresse 0.0.0.0 angeben kannst. Wenn du hier als Datentypen IpAddress angibst, kannst du auf if (host == IpAddress.None) prüfen.
    4.) Mach Statusänderungen (Verbindung aktiv/geschlossen) nicht selber aus, sondern lasse sie dir über Getter liefern
    5.) Underscores (also _ vor Variablennamen würde ich grundsätzlich nur bei sog. Backing Fields machen. Also wenn eine Klasse eine Property hat, welche das PropertyChanged Event auslöst. Hier ist es sinnvol sich eine private Variable zu machen, die so heißt, wie die Property, nur mit einem Underscore. Wenn du den Wert durch eine Funktion/Prozedur setzt, empfielt es sich die Property CamelCase, das BackingField lowerCamelCase mit Underscore/Unterstrich und den Parameter nur lowerCamelCase zu machen.

    Lg Radinator
    In general (across programming languages), a pointer is a number that represents a physical location in memory. A nullpointer is (almost always) one that points to 0, and is widely recognized as "not pointing to anything". Since systems have different amounts of supported memory, it doesn't always take the same number of bytes to hold that number, so we call a "native size integer" one that can hold a pointer on any particular system. - Sam Harwell
    @Radinator Ich danke Dir für die Hinweise. Ich setze mich nachher noch einmal dran und baue das ganze nach Euren Hinweisen um (Danke auch an @Trade).
    Dabei werde ich mir noch das Projket von @ErfinderDesRades genauer anschauen, runtergeladen hab ichs schon....
    Ich dachte ich hätte soweit alles verstanden :-(, aber das ist nochmal ne ganz andere Hausnummer als ein schnödes DataSet Only Ding.

    Da ich aber mehr und mehr Datenverarbeitungs- und Datenanzeige Tools benötige und das auch noch auf verschiedenen Platformen erwünscht ist, muss ich den Weg gehen....

    Danke Euch, meld mich wieder...
    "Hier könnte Ihre Werbung stehen..."

    MichaHo schrieb:

    Es gibt nun eine MainModel Klasse und eine MainViewModel.
    Das findich auch sehr fragwürdig.
    Welche Aufgabe hat das, was bei dir "Mainmodel" heisst (und warum heisst es nicht wie seine Aufgabe ist)?
    Welche Aufgabe hingegen hat das MainViewmodel? Nur alles kapseln, und dann das gekapselte doch durchreichen ist keine Aufgabe, sondern nur ganz viel doppelt gemoppelter Code, und damit bäh! ;)
    Viele MVVM-Propheten, bes. c#ler, propagieren ja diese doppel-moppelei, aber das ist falsch verstandenes MVVM - sagen zumindest andere.

    Wie dem auch sei - zumindest mitte Mainmodels: In meiner Welt gibts nur ein MainViewmodel, das ist das Root-Objekt mit lauter Properties - einige davon sind Viewmodel, einige Commands.
    Manchmal nenne ich das MainViewmodel auch (ungenau) "Mainmodel" - nur beides - MainViewmodel und Mainmodel - das gibts nicht.

    das mit deinen Helpers und den Testdaten war mir zu hoch
    naja, du hast das Projekt jetzt ja geladen, uns siehst, wie die Testdaten inne Xaml-Vorschau sofort sichtbar sind: sobald man ein Binding richtig setzt, erscheinen inne Vorschau richtige Daten: "Person1, Person2, Person3,..."

    Zumindest der Nutzwert, und wie's inne Praxis dann rauskommt, sollte dir also nu nicht mehr "zu hoch" sein.

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

    @ErfinderDesRades Okay, das ist interessant. Also sollte man lieber direkt ans Model binden statt alles zu kapseln?

    Grüße
    #define for for(int z=0;z<2;++z)for // Have fun!
    Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

    Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:
    Hi,
    Danke für Eure Hinweise.
    Bin gerade unterwegs, melde mich aber morgen früh aber nochmal dazu, so ganz einig bin ich da noch nicht. Ich verstehe was ihr meint, aber wiederspricht dies nicht dem Konzept von MVVM?
    "Hier könnte Ihre Werbung stehen..."
    Ich sehe sowas immer pragmatisch - ein Konzept-entsprechen nur um des Konzept-entsprechens Willen ist für mich wertlos, und trifft glaub die Definition des Begriffes "Dogmatismus".
    Wichtig an Konzepten ist doch, dass sie Anleitung geben, Probleme zu lösen, zu vereinfachen - bzw. auch zu vermeiden.
    Ergibt sich aus einem Konzept eine erhöhte Umständlichkeit ohne erkennbaren Gewinn - dann stimmt irgendwas nicht - mit dem Verständnis? mit der Umsetzung? oder gar mit dem Konzept selber?
    Das sind wirklich offene Fragen, ich weiß wirklich nicht, ob ich MVVM richtig verstehe, ob ich iwelche Gewinne übersehe, oder ob andere sich irren oder whatever.
    Oder sind meine Problemstellungen viel zu klein, und erst in größeren Rahmen würde sich die Voll-Ausbildung des Patterns als wirklich not-wendig erweisen?

    Aber mal konkret:
    Hab vor einiger Zeit an einer Zeiterfassung gewerkelt, mit Kern-Arbeitszeiten (40h-Woche), "gemessenen" Arbeitszeiten, Tätigkeiten, etc..
    Wieder war Model und Viewmodel eins, weil das Model enthielt die gemessenen Arbeitszeiten, und die gemessenen Arbeitszeiten waren auch anzuzeigen - also was sollte ein zwischengeschobenes Viewmodel bringen?
    Aber dann war eine Monats-Ansicht zu gestalten, und das war etwas, was das Model nicht hergab - dort gabs nur von wann bis wann wer gearbeitet hat, aber nicht nach Monaten strukturiert.
    Und hier brauchten wir klar ein Viewmodel, also das Modell eines Monats, dass man das View dranbinden konnte.
    Und wurde nur fürs View gebraucht - inne Datenbank hat das ja nix verloren.

    Sowas ist denke ich ein Viewmodel, und dann scheint MVVM auf einmal auch mit allen 3 Schichten absolut stimmig - ich hoffe du verstehst wassich meine.
    Hallo @ErfinderDesRades ich verstehe Dich :)
    Mein Projekt mit dem Auslesen der aktuellen Temperaturen ist wahrlich etwas zu klein für MVVM.
    Ich verstehe MVVM so:
    Du hast das Model, das liefert die Daten, egal wo die herkommen (das kann eine DB sein, eine Textdatei, ein Temperaturserver etc.)
    Das Model kennt das ViewModel nicht und kennt auch das View nicht....
    Das ViewModel ist quasi die unsichtbare Gui. hier steckt die ganze Logik drin, die die Daten aus dem Model verarbeitet/aufbereitet.
    Für verschiedene Aufagben gibt es verschiedene ViewModels. (zBsp. zum Anzeigen der Daten, zum Verarbeiten der Daten, zum Ändern der Daten).
    Das ViewModel kennt natürlich das Model, kennt aber die View nicht.
    Das View kann wiederum auch mehreres sein, eine WPF Gui, eine Android Gui, eine iOS Gui, eine Web Gui.
    Und zu jedem ViewModel gehört auch ein eigenes View und das View kennt sein ViewModel.

    Den Sinn dahinter verstehe ich so, das quasi alles austauschbar ist. Ich kann die WPF gui gegen eine Android Gui tauschen, ich kann das Model austauschen indem ich die Daten nicht mehr direkt aus ner Textdatei bereit stelle sondern eventuell aus ner Datenbank.

    Das war auch der Punkt, was mir an MVVM gefällt. In Verbindung mit EF fänd ich es grandios wenn..... ja wenn mans denn richtig versteht :) (da haperts scheints noch).

    Ich hab aktuell ein größeres Projekt (momentan noch in meinem Kopf), aber bei diesem Projekt denke ich, findet MVVM, EF und WPF auf jeden Fall seine Berechtigung.

    Ich möchte aber noch auf die anderen Hinweise eingehen:

    Trade schrieb:

    this kannst Du btw weglassen

    Ich hab das in den Einstellungen so eingestellt, weil man immer liest das Klassenvariablen dadurch besser lesbar sind.
    Wenn ich aber Recht überlege und die Hinweise zur Namensgebung von @Radinator anschaue, kann mans wirklich weg lassen, denn dann sieht man bereist an der Schreibweise was wo hin gehört.
    Und wenn ich es dann nun richtig verstanden habe, ist das so gemeint:

    C#-Quellcode

    1. bool isValid; //private Klassenvariable
    2. public bool IsValid {get;set} //öffentliche Property
    3. //gekapselte öffentliche Property
    4. bool _isValid;
    5. public bool IsValid
    6. {
    7. get{
    8. return _isValid;
    9. }
    10. set{
    11. _isValid = value;
    12. OnPropertyChanged("IsValid")
    13. }
    14. }
    15. //Konstruktor mit Parameter
    16. public Konstruktor(bool isValid)
    17. {
    18. IsValid = isValid;
    19. }

    Richtig?
    Mein neues Projekt wird ein großes Thema werden (glaub ich).
    Da soll es darum gehen, das Anträge an die IT gestellt werden können, zum Beispiel für die Beschaffung von IT-Material für neue Mitarbeiter, oder die Sperrung von Benutzern beim Ausscheiden, oder der Arbeitsplatzumzug und damit verbunden der Umzug der LAN Ports, Telefon usw.
    Da werden dann Berechtigungen gebraucht für Benutzer, Bearbeiter und Administrator
    Ne Datenbank wird gebraucht für Mitarbeiter, IT-Materialien usw. usw.
    Reports werden benötigt, Workflows usw.
    Uff...
    Daher würde ich gerne das Prinzip (DesignPattern) MVVM verstehen...

    So, ne Menge Text....
    "Hier könnte Ihre Werbung stehen..."

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

    Noch ein paar Gedanke meinerseits:

    MichaHo schrieb:

    Du hast das Model, das liefert die Daten, egal wo die herkommen
    Würde ich persönlich nicht so sehen. Die Daten bekommst du nicht vom Model sondern durch deinen Data Access Layer (DAL). Das Model ist nur das Modell, also wie im normalen OOP der Unterschied zwischen Klasse (=Bauplan) und dem Objekt. Das Model beschreibt nur WAS du anzeigen/persistieren kannst/willst/tust. Der DAL braucht Kenntniss des Model(-namespaces) und kann dir dann eine IEnumerable<T> oder einfach ein Objekt liefertn, dessen Properties du dann im ViewModel dann auf die Properties des ViewModels verteilst. Um das mit dem DAL leicht verwendbar zu machen, bietet sich hier das SOLID Prinzip an. Dazu einfach das D (Dependency Inversion) verwenden: Hierzu entweder im Kontruktor des ViewModels ein Interface erwarten, von dem es eine Klasse gibt, die dir die Daten bereitlegt oder eine LoadData Methode implementieren, welche im Konstruktor aufgerufen wird und die Daten läd (sagt ja schon der Name). Dadurch kannst du Mocking/Unit Tests fahren und schauen, ob die Daten richtig geladen werden.
    Außerdem: Eine Klasse sollte immer nur eine einzige Aufgabe haben (nicht wie bei dir mehrere: ViewModel sein, also Daten bereitstellen UND die Daten auf noch aus einer Datenquelle liefern)

    MichaHo schrieb:

    Für verschiedene Aufagben gibt es verschiedene ViewModels
    Ich würde es anders formulieren: Für jede(s) View gibt es ein eignes ViewModel. Denn das View hält ja nur die Daten bereit, das/die View zeigt sie nur an. Ob die Oberfläche in Deutsch/Japanisch/Türkisch/Klingonisch angezeigt werden soll ist doch dem View egal.

    MichaHo schrieb:

    eine WPF Gui, eine Android Gui, eine iOS Gui, eine Web Gui.
    Irgendeine GUI, welche Datenbindung unterstützt.

    MichaHo schrieb:

    ich kann das Model austauschen
    Wie in #1: Das Model nicht. Nur den "DataProvider", also ob die Daten in Deutsch, Englisch, Klingonisch, Türkisch aus einer DB, Text-Date oderWebService kommen sollen. Schau dich mal hier um: Lokalisierte Model Entity Wpf

    MichaHo schrieb:

    indem ich die Daten nicht mehr direkt aus ner Textdatei bereit stelle sondern eventuell aus ner Datenbank.
    Wie gesagt: Woher du die Daten bekommst ist oder bzw sollte dem ViewModel egal sein, das ViewModel braucht nur eine Referenz auf ein Objekt, welche Daten liefern kann. Das und nur das kannst du austauschen.
    Wenn du z.B. als Model die Klasse Auto hast - und sie dir auch gleich die Daten für einen Audi A7 mit x Extras liefert (was sie nicht soll, aber jetzt mal egal), dann kannst du nicht einfach hergehen und (weil du grad lustig bist) das Model, also die Klasse "Auto", durch "Mensch" austuschen, welche dir - hier auch wieder: Sinnhaftigkeit... - das Model "Mensch" meinetwegen das Objekt "Usain Bolt" leifert. Objekt "Usain Bolt" hat aber nunmal keine Property "PS", sondern nur "MaximalLeistung". Und genau hier "knallt" es. Bzw es wird dir halt einfach nix (PS und MaximalLeistung) angezeigt.
    Deswegen: Nie das Model austauschen!! Immer nur die Klasse/das Objekt, welche dir die Daten liefert.

    MichaHo schrieb:

    kann mans wirklich weg lassen, denn dann sieht man bereist an der Schreibweise was wo hin gehört.
    Ich persönlich schreib halt immer lieber this davor, da ich dann ganz sicher sein kann - auch wenn ich den Code nur überfliege - dass diese Property/diese Variable auch zu der Klasse gehört.
    Außerdem: Ist halt eine alte Angewohnheit. Meist lass ich das sowieso weg, aber gerade, wenn ich Code teile und ich da nur Snippets poste, dann erleichtert es - meiner Meinung nach schon - wenn ich this verwende. Vor allem: Gesetzt dem Fall, ich poste einen Ausschnitt einer Funktion, dann ist es einfacher zu sehen: Ah, die Variable hier ist nicht im lokalen Kontext gesetzt, sondern eine Klassenvariable.

    Lg Radinator
    In general (across programming languages), a pointer is a number that represents a physical location in memory. A nullpointer is (almost always) one that points to 0, and is widely recognized as "not pointing to anything". Since systems have different amounts of supported memory, it doesn't always take the same number of bytes to hold that number, so we call a "native size integer" one that can hold a pointer on any particular system. - Sam Harwell
    ich auch nochmal.

    Also wie Radinator sagt: Model holt nicht die Daten, sondern es ist der Ort (meist ein zusammenhängendes System von Klassen), wo die (via DAL) geholten Daten reingetan werden, um inne Anwendung verfübgbar zu sein.
    Anders als bei Radinator hat bei mir nicht jedes View sein eigenes Model, sondern wenn sich Elemente des Model eh schon eignen, um ein View dranzubinden - da treib ich keinen Zusatz-Aufwandt.

    Ähnlich mit Dependancy-Injection: Probiers aus, und guck, obs dir Gewinn bringt.
    Ich find die Kosten-Seite nicht ohne:
    • DI-Container installieren/einbinden
    • Interfaces anlegen + pflegen
    • ganz viele Casts, und umständliche Instanzierungen
    Die Samples, die ich gesehen habe, die waren eiglich immer viel einfacher mit einem statischen Objekt abgehandelt, wo man ebensogut die Sachen holen konnte, die man brauchte.
    Und letztendlich ist so ein DI-Container auch nix anneres als ein statisches Objekt, wo man Sachen holen kann (muss man halt registrieren etc.)
    Sooo Leuts.... ich glaub JETZT hab ich geschnallt was MEIN Fehler ist bei Model und ViewModel und View....
    Geh ich mal wieder auf mein Beispiel mit den Temperatur Server....
    Da hatte ich ja die 3 Klassen MConnection, Mserver und MValue (Kann man ja in eine Klasse packen und dann DAL nennen).
    anstatt dann eine neue Klasse MainModel zu erstellen, muss ich einfach in der ViewModel (was dann die Klasse ist, die sich die Daten holt und zur Anzeige bereit stellt) nur die Daten eben abholen und in Properties ablegen...
    Das View kann die dann anzeigen oder auch ein anderes View kann die bearbeiten und zurück schreiben...
    Mir ist so als hätten alle beteiligten mir das auch so gesagt, nur ich Blödmann habs nicht gerallt weil ich immer an das Model gedacht hab.... (nein, nicht an das mit den langen Beinen :) )
    Und dann macht auch alles Sinn, auch was @ErfinderDesRades sagt, das ER nur ein ViewModel hat, also eine Klasse die Daten holt und bereit stellt...
    Nun gut, dann setze ich mich nachher mal drann, das neu aufzustellen und lade das Projekt dann hier hoch...
    Danke Euch für den verbalen Tritt :)
    "Hier könnte Ihre Werbung stehen..."

    ErfinderDesRades schrieb:

    Anders als bei Radinator hat bei mir nicht jedes View sein eigenes Model
    Da ich bisher noch keine Anwendung hatte, die mehr als 1 View hatten, bestand bei mir auch (Gott sei Danke) nicht der Bedarf, ein ViewModel für mehrere Views zu verwenden.

    Allerding ist es IMHO immer eine Sache der Anwendung, OB für jedes View ein eigenes ViewModel gebraucht wird oder ein ViewModel für mehrer Views verwendet werden kann. Also von Anwendung zu Anwendung unterschiedlich. So wird ein

    Allerding ist es IMHO sinnlos in einer Anwendung ein ViewModel für mehrere Views zu verwenden. So ist es bspw wenig ratsam 1 Anwendung, 1 ViewModel zu haben, wenn eine View die eigentliche Oberfläche zeigt, die zweite dann diverse Einstellungen und die dritte dann noch mal ganz anderen Content. Hier sollte man wie gesagt für jede View ein eigenes ViewModel anlegen. Und ich kann die Aussage sogar belegen: SOLID Prinzip, Single-Responsibility-Prinzip: Das Single-Responsibility-Prinzip besagt, dass jede Klasse nur eine einzige Verantwortung haben solle

    Lg Radinator

    MichaHo schrieb:

    muss ich einfach in der ViewModel (was dann die Klasse ist, die sich die Daten holt und zur Anzeige bereit stellt) nur die Daten eben abholen und in Properties ablegen
    Jup :D
    In general (across programming languages), a pointer is a number that represents a physical location in memory. A nullpointer is (almost always) one that points to 0, and is widely recognized as "not pointing to anything". Since systems have different amounts of supported memory, it doesn't always take the same number of bytes to hold that number, so we call a "native size integer" one that can hold a pointer on any particular system. - Sam Harwell
    Hi,
    so, ich hab jetzt mal das Beispiel umgebaut.
    Es gibt 1 Klasse: Measurement und 1 View.
    Im Konstruktor der Klasse wird der Wert abgeholt und in eine Property geschrieben. Ein Label ist an die Property gebunden.

    Klappt sehr gut.
    Es klappt im Moment halt nur für einen comport den ich beim Instanzieren mitgebe...
    Dateien
    • Measurement02.zip

      (9,99 kB, 185 mal heruntergeladen, zuletzt: )
    "Hier könnte Ihre Werbung stehen..."
    Das Ding ist tatsächlich zu klein, als dass Verbesserungsvorschläge da überzeugen könnten.
    ZB gibts kein INotifyPropertyChanged, also wenn MValue sich mal ändern würde, würde die Oberfläche das nicht mitbekommen.
    Und nachwievor haste im CodeBehind

    C#-Quellcode

    1. this.DataContext = new Measurement("pcmeasure.com1.1");
    Also hast noch nie ühaupt gesehen, wie man mittm Xaml-Editor Bindings "picken" kann.
    Hi @ErfinderDesRades ich hab in deinem Beispiel nachgeschaut wie man das im Xaml macht, bei mir hat es nur nicht geklappt, der kam irgendwie mit den Namespaces durcheinander, deswegen hab ichs nochmal im Code Behind gemacht.

    Ein anderes Projekt zwingt mich auch gerade erstmal wieder auf WinForms mit c# umzusteigen... Au Mann...
    "Hier könnte Ihre Werbung stehen..."