Bitte um Bewertung meines zweiten Projektes - Tea Timer

    • Release
    • Open Source

    Es gibt 68 Antworten in diesem Thema. Der letzte Beitrag () ist von petaod.

      Bitte um Bewertung meines zweiten Projektes - Tea Timer

      Name:
      Tea Timer Professioal

      Beschreibung:
      Ein Teatimer mit erweitertem Funktionsumfang:
      zwei Timer: 1. Abkühlzeit des Wassers, 2. Ziehzeit des Tees
      Speicher- und editierfunktion in einer kleinen Dataset only Datenbank für Teeame, Wassertemperatur, und Ziehzeit
      Einstellungenform, für verschiedene Einstellungen

      Verwendete Programmiersprache(n) und IDE(s):
      VB.Net Visual Studio 2017


      Hallo ihr lieben
      Ich präsentiere euch hier mein zweites Vb.Net Programm, und bitte euch den Code zu bewerten.
      Bitte nicht über de Sinn und Zweck der Funktionen nachdenken, diente mir mehr als Übung :)

      Edit1: Was wichtiges veregssen.
      Ich nutze in diesem Projekt die Helpersdatei vom ErfinderdesRades!
      Also die extern eingebundene Helpers Datei ist nicht von mir (auch wenn das bestimmt eh jeder hier weiß :)

      Edit2: Projekt neu hochgeladen, inklusive der vormals fehlenden Helpers
      Dateien
      • Tea Timer.zip

        (1,32 MB, 31 mal heruntergeladen, zuletzt: )

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

      Ich habe die Solution noch nicht in VisaulStudio geöffnet sondern mir erstmal die Struktur angesehen.
      Dabei ist mir direkt aufgefallen das du Form1, Form2, Form3 ect. hast. Benamung sehr schlecht gewählt, wenn überhaupt gewählt.
      Rechtschreibfehler betonen den künstlerischen Charakter des Autors.
      Weit bin ich nicht gekommen.
      Nach dem Archiverstellen solltest Du den Inhalt immer nochmal an anderer Stelle auspacken und das Projekt öffnen, um sicherzugehen, dass es funktioniert. In diesem Fall geht es nicht, da ein falscher Ordnerverweis in der .sln drin ist.
      F:\EdR\Helpers\HelpersSmallEd\HelpersSmallEd.vbproj : error : Die Projektdatei konnte nicht geladen werden. Ein Teil des Pfades "F:\EdR\Helpers\HelpersSmallEd\HelpersSmallEd.vbproj" konnte nicht gefunden werden. F:\EdR\Helpers\HelpersSmallEd\HelpersSmallEd.vbproj
      Die EdR-Helpers sind leider nicht dabei.
      Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

      Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
      Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.
      Ich nehme bereits am Namen Anstoss: "Professional" - der Name kann ja garnet stimmen - du sagst doch selbst, es ist eine Fingerübung.
      Mag vlt. kleinlich erscheinen - oder im Gegenteil: übertrieben, aber der Grundsatz mit der richtigen Benamung - das ist nicht nur im Code anwendbar, sondern auch auf den Namen des Programms, überhaupt auf alle Begriffe, die man benutzt - letztendlich sogar auf das Denken selbst.

      Ansonsten fehlt dem Zip das HelpersSmallEd-Projekt, und daher kanns nicht kompilieren.

      Aber gut gefällt mir:
      • https://www.vb-paradise.de/index.php/Thread/105413-Visual-Studio-Empfohlene-Einstellungen/?postID=949977#post949977 vollständig umgesetzt ist (naja - ich hötte noch paar mehr Generalimporte rausgeworfen).
      • der Klassen-Code ist kurz
      • Verwendung einer Helpers-Bibliothek
      • Verwendung typDataset - allerdings ist das iwie in den My Project-Ordner verrutscht - da gehörts nicht hin, und da findet mans auch kaum.

      Das mitte Form-Benamung scheint auch ein Missverständnis.
      Weil in den Form.vb - Dateien drin sind eiglichen die Form-Klassen ordentlich benamt - man müsste nur die Dateien nu auch noch entsprechend umbenennen.
      Klar kann man jede Menge verbessern, aber soweit ich sehe in jeder Beziehung finde ich, dass ein guter Weg beschritten wurde.

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

      Hallo ihr lieben
      Zunächste mal vielen Dank fürs ansehen meines Projektes :)
      Eins vorweg - als VBAler verwirrt mich dieser ganze Projektmappeexplorer immeroch, also bitte seid da etwas nachsichtig mit mir :)

      Ich habe das Projekt unter meinem Eingangspost erneut hochgeladen.
      Helpersprojekt und mein Tea Timer Projekt befinden sich jetzt im gleichen Hauptordner, jeweils in eigenen Unterordnern (beide sind in der zip enthalten) - ich hoffe so macht man das so :)
      Die entpackte zip (aus dem Anhang oben) läuft bei mir einwandfrei - also hoffe ich mal wars richtig.

      @Akanel: Die vb Dateien haben jetzt einen sprechenden Namen.
      Ich habe nur die Klassen in diesen Dateien entsprechend benannt, die vb Dateien hab ich einfach vergessen.

      @ErfinderDesRades
      Zum Namen: wenn man genau drüber nachdenkt hast du wohl recht. profesionall...
      Mir war einfach nur Tea Timer irgendwie zu langweilig und weil ja doch Funktionen enthalten sind, die ein "normaler" Timer nicht hat, hab ich ein Professional rangeklatscht. Aber ich verstehe worauf du hinaus willst.

      Was das Dataset im MyProject Ordner veloren hat weiß ich auch nicht so ganz, aber ich denke das kann ich ja einfach da rausziehen und in einen schicken neuen Ordner schmeißen. Wenn mein Projekt dann nicht mehr läuft, weiß ich dass das doch nicht ging :)

      Der Rest, holla, klingt ja so als hätte ich mir die gefühlten 100 Youtube Tutorials doch nicht umsonst angeschaut. Danke! :D

      Da ich aber eigentlich "großes" vorhabe - nämlich die Umwandlung eines fertigen VBA Programmes in Excel (bzw. eigentlich mehrerer) mit ca. 70.000 Zeilen Code in ein VB.Net Programm (eben dann ohne Excel) und aus meiner VBA Anfangszeit weiß wie ätzend es ist, wenn man erstmal falschen Müll für richtig hält und darauf aufbaut, bis man merkt, dass man bestimmte Dinge einfach anders (besser) macht.
      Dann kostet es irgendwie ganz schön viel Zeit einen (laufenden) Mistcode zu einem gescheiten Code umzuwandeln und den falsche Müll wieder ausm Gehirn zu verdrängen.
      Jetzt bin ich irgendwie von meiner Hauptaussage abgekommen, also zurück.
      @ErfinderDesRades
      Du sagst, es wurde zwar ein guter Weg beschritten, aber man kann jede Menge verbessern.
      Könntest du dies, natürlich ohne Eile, ein bisschen genauer Ausschmücke? Also was genau sollte ich verbessern?
      Es fängt dabei an, dass als Startformular Form1 eingetragen ist - was es aber gar nicht gibt.
      frmNeu ist heißt in Wirklichkeit frmTableChange.
      Form3 wird in den Anwendungseinstellungen aufgelistet, aber nicht im Projektexplorer.

      VB.NET-Quellcode

      1. Private Sub Temperaturaendern(Faktor As Integer)
      2. 'Sub zum ändern der Temperatur
      3. Dim Temperatur As Integer = Integer.Parse(lblTemperatur.Text)
      4. Temperatur = Temperatur + Faktor
      5. If Temperatur > 100 OrElse Temperatur < 60 Then Exit Sub
      6. lblTemperatur.Text = Temperatur.ToString
      7. End Sub
      Faktor? Wieso Faktor? Faktor impliziert Multiplikation, keine Addition.
      Deine Ist-Temperatur sollte sich nicht aus einem Label speisen, sondern anders herum -> Mach Temperatur zu einer Klassenvariablen.

      VB.NET-Quellcode

      1. Private Sub Abkuehlzeitschreiben(Temp As Integer, NudMin As NumericUpDown, NudSek As NumericUpDown)
      2. If Temp >= 60 Then
      3. NudMin.Text = (Temp \ 60).ToString
      4. NudSek.Text = (Temp Mod 60).ToString

      Deine Variablennamen sind etwas verwirrend. Temp als Temperatur oder temporär? Aber beides verwirrend.

      VB.NET-Quellcode

      1. Case = 95 : TemperaturinZeit(My.Settings.Temp95)
      2. Case 90 : TemperaturinZeit(My.Settings.Temp90)
      3. Case = 85 : TemperaturinZeit(My.Settings.Temp85)
      Etwas inkonsistent.
      Hier auch: Dim Sekunden As Decimal = Integer.Parse(lblZiehzeitSekunden.Text)
      If Minuten < 10 Then lblZiehzeitMinuten.Text = "0" & Minuten.ToStringThema String.Format; da kannst Du Dir die Führungsnull sparen.
      i = i + 1 -> i += 1

      VB.NET-Quellcode

      1. Dim Spalte = DirectCast(DirectCast(DTTeesortenBindingSource.Current, DataRowView).Row, DTTeesortenRow)
      2. DataSet1.DTTeesorten.RemoveDTTeesortenRow(Spalte)
      -> DTTeesortenBindingSource.RemoveCurrent
      MessageBox.Show("der letzte Eintrag kann nicht gelöscht werden")Warum nicht?

      VB.NET-Quellcode

      1. Public Zeit As Integer
      2. Public Ziehen As Boolean
      3. Public Sound As Boolean
      Public Variablen = code smell ;)

      Das für's erste schnelle Überfliegen.
      Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

      Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
      Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.

      DerSmurf schrieb:

      Da ich aber eigentlich "großes" vorhabe - nämlich die Umwandlung eines fertigen VBA Programmes in Excel (bzw. eigentlich mehrerer) mit ca. 70.000 Zeilen Code in ein VB.Net Programm (eben dann ohne Excel)
      Ich habe schon Giganten in VBA geschrieben.
      Aber ich glaube nicht dass eines davon auch nur annähernd so viele Zeilen hatte.

      Deshalb meine Vermutung:
      Der Code ist nicht besonders gut und schon gar nicht objektorientiert.
      Da ist (nicht nur aufgrund der Portierung) wohl ein komplettes Redesign vonnöten.
      Analysiere den Code, gruppiere ihn und mache ein objektorientiertes Design daraus.
      Einzelne Codeelemente wie Algorithmen kannst du ggf. 1:1 portieren.

      Aber ohne Redesign wird aus einem Spaghetti-Code ein chaotischer, fehlerdurchzogener Spaghettini-Auflauf.

      Ist nur eine Vermutung, aber ich würde eine kleine Summe darauf verwetten.
      --
      If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
      --
      Hallo ihr beiden!
      Sorry! das sollte nicht 70.000 Zeilen Code sondern 10.000 heißen!
      Allerdings ist dies ein geschätzter Wert.

      Der Funktionsumfang ist dabei wirklich gigantisch.
      Deine Vermutung einen spaghettihaften, von Fehlern durchzogenge Code vorzufinden kann ich direkt verneinen.
      Das stimmt (nachdem ich das Programm 2 mal komplett redesigned habe) nicht mehr.
      Natülich würde ich, wenn ich heute das gleiche Programm noch einmal schreiben würde, manches anders machen.

      Allerdings hatte ich ohnehin vor diesen Code nach Abschluss des jetzigen Tea Timer Projektes als Programmvorstellung mal vorzustellen.
      Denn aus Erfahrung weiß ich ja mittlerweile, dass es bei einem solchen Projekt sehr hilfreich ist, sich vorher gründliche Gedanken über die Umsetzung zu machen. (Das spart mir dan vielleicht ein Redesign...)
      Vielleicht mag mich ja dann auch jemand bei der Umetzung von VBA in VB.Net unterstützen.
      Denn ich habe zum Beispiel immer noch keine Ahnung, wie ich die anfallenden Daten am sinnvollsten speichern soll (ist ja kein Excel mehr im Hintergrund).
      Aber dazu später mehr.

      Erstmal bin ich dabei meinen Tea Timer nach Vaporized's Kritik zu überarbeiten, finde nur gerade leider sehr wenig Zeit :(

      DerSmurf schrieb:

      Deine Vermutung einen spaghettihaften, von Fehlern durchzogenge Code vorzufinden kann ich direkt verneinen.
      Das liegt im Auge des Betrachters. Spaghetticode kann für den einen oder anderen für uns auch schon sein, wenn man nicht objektorientiert programmiert, sondern Einstellungen und Verhalten von Dingen, die gekapselt in eine eigene Klasse gehören, über ein oder mehrere Forms verteilt. ;)
      Speichern und Laden: Es gebe z.B. CSV-Dateien, das DataSet*, oder auch Entity Framework mit/ohne Anbindung an eine DB.

      * Schau mal bei EdRs VVV rein. Da gibt's genügend Infos zum schnellen Einstieg.
      Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

      Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
      Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.
      Ja nagut.
      Dann findet ihr vielleicht doch spaghetticode :)
      Allerdings möchte ich den Code ja eh nicht "kopieren" sondern ein "neues" Programm schreiben, mit gleichem, bzw. dann erweitertem Umfang.
      Aber gut, es sieht aus, als käme so oder so das Redesign Nummer 3 meines Projektes...
      Wahrscheinlich ist es dann sogar sinnvoller, nur den Funktionsumfang des Programmes zu beschreiben, das sollte es den Helfern leichter machen, weil das inspizieren meines Codes (einigen wir uns auf "Code der ganz in Ordnung ist" :) wegfällt.
      Und ich komme garnicht erst auf die Idee mich an alten Code zu klammern.
      Aber eins nach dem anderen.

      Die Vier Views vom EdR sind mir ein Begriff, die Videos habe ich nach mehrmaligem schauen dann auch endlich mal verinnerlicht (hoffe ich:)
      Diese Einführung von ihm brachte mich auf die Idee in diesem Tea Timer ein kleines DataSet einzubauen, um ein bisschen damit rumzuspielen.

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

      So lieber @VaporiZed
      Nun habe ich endlich mal Zei, deine Kritik umzusetzen, bzw. mich damit zu befassen.
      An dieser Stelle nochmal vielen Dank dafür!

      Aufgrund deiner Formulierung habe ich mal unten angefangen, das scheint einer der schlimmsten Dinge zu sein.
      Public Variablen = code smell

      Also 1.:
      Spoiler anzeigen
      Dies habe ich nun wie folgt geändert (und globale Klassenvariablen werde ich nie wieder verwenden. Isch schwör!)

      Quellcode

      1. Public Class fTimer
      2. Private Zeit As Integer
      3. Private Ziehen As Boolean
      4. Private Sound As Boolean
      5. 'Propertys
      6. Public WriteOnly Property SetZeit() As Integer
      7. Set(ByVal value As Integer)
      8. Zeit = value
      9. End Set
      10. End Property
      11. Public WriteOnly Property SetZiehen() As Boolean
      12. Set(value As Boolean)
      13. Ziehen = value
      14. End Set
      15. End Property
      16. Public WriteOnly Property SetSound() As Boolean
      17. Set(value As Boolean)
      18. Sound = value
      19. End Set
      20. End Property


      Quellcode

      1. ...
      2. 'Wenn Abkühlzeit größer als 0, dann zeigen der Form fTimer Abkühlen
      3. If Abkuehlzeit > 0 Then
      4. Dim frmAbkuehlzeit As New fTimer
      5. With frmAbkuehlzeit
      6. .SetSound = Sound
      7. .SetZeit = Abkuehlzeit
      8. .SetZiehen = False
      9. .ShowDialog(Me)
      10. End With
      11. End If
      12. 'zeigen der Form fTimer für die Ziehzeit
      13. Dim frmZiehzeit As New fTimer
      14. With frmZiehzeit
      15. .SetSound = Sound
      16. .SetZeit = Ziehzeit
      17. .SetZiehen = True
      18. .ShowDialog(Me)
      19. End With[/spoiler][spoiler]


      2.
      MessageBox.Show("der letzte Eintrag kann nicht gelöscht werden")Warum nicht?

      Spoiler anzeigen
      Mein Spaltefinden und löschen Mist ist gelöscht und durch dein RemoveCurrent ersetzt.
      Tja, das löschen des letzten Eintrages verursacht einen Fehler, der wohl mit hiermit zusammenhängt:
      Deine Ist-Temperatur sollte sich nicht aus einem Label speisen, sondern anders herum -> Mach Temperatur zu einer Klassenvariablen.

      Gibt es in der Binding Source nämlich keinen Eintrag mehr, ist das LblTemperatur.Text =""
      Dies verursacht dann in der lblTemperatur_TextChanged einen Fehler:

      Quellcode

      1. 'Temperatur aus lblTemperatur auslesen und Abkuehlzeit entsprechend ändern
      2. Dim Temperatur As Integer = Integer.Parse(lblTemperatur.Text)

      Dies habe ich jetzt (erstmal) wie folgt gelöst (mir ist bewusst, dass das Problem eigentlich ein anderes ist, aber hierzu habe ich Fragen):

      Quellcode

      1. Private Sub lblTemperatur_TextChanged(sender As Object, e As EventArgs) Handles lblTemperatur.TextChanged
      2. 'Temperatur aus lblTemperatur auslesen und Abkuehlzeit entsprechend ändern
      3. Dim Temperatur As Integer
      4. Dim Zahl As Boolean = Int32.TryParse(lblTemperatur.Text, Temperatur)
      5. 'Dim Temperatur As Integer = Integer.Parse(lblTemperatur.Text)
      6. If Zahl = False Then
      7. lblTemperatur.Text = "100"
      8. End If
      9. Select Case Temperatur
      10. Case = 100 : TemperaturinZeit(0)
      11. Case = 95 : TemperaturinZeit(My.Settings.Temp95)
      12. Case 90 : TemperaturinZeit(My.Settings.Temp90)
      13. Case = 85 : TemperaturinZeit(My.Settings.Temp85)
      14. Case = 80 : TemperaturinZeit(My.Settings.Temp80)
      15. Case = 75 : TemperaturinZeit(My.Settings.Temp75)
      16. Case = 70 : TemperaturinZeit(My.Settings.Temp70)
      17. Case = 65 : TemperaturinZeit(My.Settings.Temp65)
      18. Case 60 : TemperaturinZeit(My.Settings.Temp60)
      19. End Select
      20. End Sub

      Nun renne ich aber an anderer Stelle in einen Fehler, nachdem das letzte Element aus der BindingSource gelöscht wurde:

      Quellcode

      1. Private Sub Ziehzeitaendern(op As String)
      2. 'Intervall aus den Einstellungen lesen
      3. Dim Intervall As Decimal = My.Settings.Zeitintervall
      4. Dim Sekunden As Decimal = Integer.Parse(lblZiehzeitSekunden.Text)

      Nach dem löschen des Eintrages sind lblZiehzeitMinuten.Text und lblZiehzeitSekunden.Text beide ="", was ja dann Integer.Parse nicht mag.
      Also habe ich in der löschen die "Mengenprüfschleife" wieder eingebaut und setze nach dem löschen des letzten Eintrages den Text der beiden Labels auf 0:

      Quellcode

      1. Private Sub btnloeschen_Click_1(sender As Object, e As EventArgs) Handles btnloeschen.Click
      2. 'Sub zum löschen aus dem Dataset
      3. DTTeesortenBindingSource.RemoveCurrent()
      4. 'prüfen ob eine Spalte über bleibt
      5. Dim i As Integer = 0
      6. For Each dtteesortenrow As DTTeesortenRow In DataSet1.DTTeesorten
      7. i += 1
      8. Next
      9. 'Ziehzeitlabels befüllen, wenn letzter Eintrag aus BindingSource gelöscht wurde
      10. If i = 0 Then
      11. lblZiehzeitMinuten.Text = "0"
      12. lblZiehzeitSekunden.Text = "0"
      13. End If
      14. End Sub

      An dieser Stelle mal eine Frage. Kann ich leichter einen Wert für einen Control vergeben, der mit einer Binding Source verknüpft ist, wenn die BindingSource keinen Wert liefert?


      4.
      If Minuten < 10 Then
      lblZiehzeitMinuten.Text = "0" & Minuten.ToStringThema String.Format; da kannst Du Dir die Führungsnull sparen.

      Spoiler anzeigen
      alter Code:

      Quellcode

      1. [/spoiler][spoiler] 'Minuten und Sekunden ggf mit voranstehender 0 in Labels schreiben
      2. If Minuten < 10 Then
      3. lblZiehzeitMinuten.Text = String.Format()
      4. Else
      5. lblZiehzeitMinuten.Text = Minuten.ToString
      6. End If
      7. If Sekunden < 10 Then
      8. lblZiehzeitSekunden.Text = "0" & Sekunden.ToString
      9. Else
      10. lblZiehzeitSekunden.Text = Sekunden.ToString
      11. End If

      neuer Code

      Quellcode

      1. lblZiehzeitMinuten.Text = Minuten.ToString("00")
      2. lblZiehzeitSekunden.Text = Sekunden.ToString("00")[/spoiler][spoiler]


      5.inkonsistenz

      Quellcode

      1. Dim Sekunden As Decimal = Integer.Parse(lblZiehzeitSekunden.Text)

      Spoiler anzeigen
      Der Code dazu:

      Quellcode

      1. [/spoiler][spoiler] Private Sub Ziehzeitaendern(op As String)
      2. 'Intervall aus den Einstellungen lesen
      3. Dim Intervall As Decimal = My.Settings.Zeitintervall
      4. Dim Sekunden As Decimal = Integer.Parse(lblZiehzeitSekunden.Text)
      5. Dim Minuten As Integer = Integer.Parse(lblZiehzeitMinuten.Text)
      6. If op = "+" Then
      7. 'Sekunden erhöhen
      8. Sekunden = Sekunden + Intervall

      Das Problem ist, dass My.SettingsZeitintervall an eine Numeric up and down geknüpft ist - also decimal sein muss.
      Da ich später mit der Variable Intervall = My.Settings.Zeitintervall und Sekunden rechne, müssen diese ja das gleiche Format haben.
      Ich habe nun diese Dezimalzahl in eine Integer umgewandelt. Damit sollte das ganze ja nicht mehr inkonsistent sein:

      Quellcode

      1. Dim Intervall As Integer = Decimal.ToInt32(My.Settings.Zeitintervall)

      Zum nächsten eine Frage:

      Quellcode

      1. Case = 95 : TemperaturinZeit(My.Settings.Temp95)
      2. Case 90 : TemperaturinZeit(My.Settings.Temp90)
      3. Case = 85 : TemperaturinZeit(My.Settings.Temp85)

      Das benennst du auch "etwas inkonsistent" liegt das am fehlenden "Case = 90", oder hat es einen anderen Grund?
      Das Fehlende istgleich habe ich eingefügt.


      6. Variablennamen:
      Deine Variablennamen sind etwas verwirrend.
      und "Faktor"
      Spoiler anzeigen
      Ja, da hast du wohl recht.
      Beim Programmieren, fand ich Temp und Faktor irgendwie sinnvoll. Aber du hast schon recht.
      Temp wurde geändert in Temperatur, Faktor heißt jetzt Grad


      7. Die Namen der Formen:
      Es fängt dabei an, dass als Startformular Form1 eingetragen ist - was es aber gar nicht gibt.
      frmNeu ist heißt in Wirklichkeit frmTableChange.
      Form3 wird in den Anwendungseinstellungen aufgelistet, aber nicht im Projektexplorer.

      Spoiler anzeigen
      Hier tu ich mich echt schwer. Das ganze leigt wohl daran, dass ich recht viele Formen eingefügt und wieder gelöscht habe und dann die Namen der Formen nachträglich geändert habe.
      Bei der Startform bin ich verwirrt. Die Startform (die beim Start des Programmes auch angezeigt wird), heißt Hauptform.
      Diese kann ich aber nicht als Startform auswählen, weil sie nicht auftaucht. Warum nicht?
      frmNeu ist heißt in Wirklichkeit frmTableChange.
      Warum?
      Ich habe beide Formen im Projektexplorer umbenannt. In manchen Tutorials habe ich gesehen, dass beim umbenennen einer .vb Datei gefragt wird, ob auch alle Verweise oder so ähnlich) umbenannt werden sollen. Diese Meldung kam bei mir nicht, liegt es vielleicht daran?
      Wie benenne ich dann eine Form nachträglich? Google liefert nur ein umbenennen über den Projekt Explorer und im aufpoppenden Fenster "alle Verweise aktualiseren" mit ja bestätigen - aber es gibt ja kein Popp Fenster :(
      Gleiches bei Form 3. Diese habe ich im Projektexplorer gelöscht. Habe auf "alle Dateien" umgestellt und dort noch ein paar Form3 Dateien gefunden. Diese habe ich nun gelöscht. Jetzt wird sie in den Anwendungseinstellungen auch nicht mehr aufgelistet.
      Eine "Form1" habe ich jedoch nicht gefunden (nur Form1save.vb)


      8.
      Deine Ist-Temperatur sollte sich nicht aus einem Label speisen, sondern anders herum -> Mach Temperatur zu einer Klassenvariablen.

      Spoiler anzeigen
      Ich mache also Temperatur zu einer Klassenvariablen und ändere dann mit meinen beiden Buttonklicks diese Variable. Ihren Wert gebe ich dann in der Textbox wieder.
      Jedoch weiß ich nicht genau, wie ich das umsetzen soll, denn das Label ist ja auch an die BindinSource geknüpft.
      Es wäre doch dann sinnvoller, dieses Binding zu lösen. Aber dann muss ich ja nach einem Klick auf das Datagridview meine Klassenvariable mit der entsprechenden Temperatur befüllen und dann wieder ins Label speichern.
      Das macht doch dann nicht so den Sinn, oder?


      edit:
      nach dem löschen von Form3 aus dem Projekt Explorer, meckert mein Programm, dass dieses fehlt.
      Ausführung ist nicht mehr möglich :(
      Wenn ich im Code (in gesamter Projektmappe) nach "Form3" suche, wird nichts gefunden.
      Wie lösche ich denn die Verweise auf eine Form manuell? Oder habe ich eine andere Möglichkeit?

      Edit2: nun ist auch noch die Form1 als wählbares Startformular verschwunden. und das eigentliche Startform "Hauptform" kann ich nicht auswählen - das taucht da nicht auf.
      Hab ich mein Projekt jetzt getötet? :(

      Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „DerSmurf“ ()

      Getötet hast Du noch nix. Du hast ja ein "Backup" in Post#1.
      Aber merke Dir: Backups machen.

      "Dies habe ich jetzt (erstmal) wie folgt gelöst (mir ist bewusst, dass das Problem eigentlich ein anderes ist, aber hierzu habe ich Fragen):"

      VB.NET-Quellcode

      1. 'Temperatur aus lblTemperatur auslesen und Abkuehlzeit entsprechend ändern
      2. '...
      3. Dim Zahl As Boolean = Int32.TryParse(lblTemperatur.Text, Temperatur)

      NEIN! lblTemperatur ist über eine BindingSource an eine Variable und somit deren Wert gebunden. Wenn Du die Temperatur haben willst, nimm diesen BindingSource-Wert. Da wird gar nix aus nem Label rausgepuhlt!
      Und wenn dann eben die BindingSource ihren letzten Eintrag verliert, dann wird das Label eben keinen Text anzeigen, sondern leer bleiben. Wozu in einem Label einen Wert anzeigen lassen, wenn kein Wert existent ist?
      Wenn Intervall vom Typ Decimal sein muss, dann belass es doch auch als Decimal. Warum dann mit Int hantieren? Ich hab aber mal einen Anfangstest gemacht: Wenn ich dem NUD einen Decimal-Setting-Wert an die Hand gebe und danach den Typ jenes Wertes in den Settings auf Integer abändere, geht das. In das NUD eingegebene Kommazahlen werden dann in Integer umgewandelt.

      DerSmurf schrieb:

      frmNeu ist heißt in Wirklichkeit frmTableChange.
      Die Datei heißt frmNeu, die Klasse darin aber frmTableChange. Wenn beide Namen übereinstimmen und man dann den Dateinamen ändert, kommt die Frage, ob der Inhalt auch abgeändert werden soll. Wenn sich Klassenname und Dateiname aber unterscheiden, kommt die Frage logischerweise nicht.

      DerSmurf schrieb:

      Eine "Form1" habe ich jedoch nicht gefunden
      Und Dein Projekt auch nicht. Der Name war aber noch als Startformular hinterlegt. Sobald man das aber abändert, also ein anderes Formular als Startform hinterlegt, wird Form1 aus der Liste entfernt.

      DerSmurf schrieb:

      Es wäre doch dann sinnvoller, dieses Binding zu lösen.
      Wenn Du ein sinnvolles Binding hast, brauchst Du Temperatur als (Klassen-)Variable überhaupt nicht mehr.

      DerSmurf schrieb:

      nach dem löschen von Form3 aus dem Projekt Explorer, meckert mein Programm, dass dieses fehlt.
      Und dann doppelklickt man auf die Fehlermeldung und kommt normalerweise an der Stelle an, wo noch ein Verweis existiert.
      Hauptform heißt die Datei. Die Klasse darin kannst Du als Startform festlegen. Und die heißt fEinstellungen. War für mich anfangs auch verwirrend, als ich mir Dein Projekt angeschaut hab. ;)
      Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

      Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
      Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.
      Ah.
      Das was in den Einstellungen als Startform gewählt werden kann, bezieht sich auf die Namen der Klassen inerhalb der vb Dateien, und nicht auf den Dateinamen der vb Datei. Dsa entwrrt mich ein wenig.
      Also macht es ja Sinn Klassennamen und Dateinamen gleich zu halten.

      Zur fehlenden Form3:
      Folgender Fehler entsteht:
      Schweregrad Code Beschreibung Projekt Datei Zeile Unterdrückungszustand
      Fehler Für "My Project\Form3.resx" kann kein Manifestressourcenname erstellt werden. Die Datei "C:\Users\flori\Documents\Visual Studio 2017\VB Programme\Tea Timer Professional\Tea Timer Professional\My Project\Form3.vb" konnte nicht gefunden werden. Tea Timer Professional

      Ein Doppelklick hierauf bringt mich leider nicht zu einem entsprechenden Verweis innerhalb des Codes.
      Auch die Suche nach "Form3" im Code der gesamten Projektmappe bringt nichts.
      Und komisch ist, wenn ich ein neues Formular erstelle, und dieses Form3 nenne, wird es mir im Projekt Explorer nur angezeigt, wenn ich auf "alle Dateien" klicke.
      Erstelle ich diese Form und starte mein Projekt erhalte ich folgenden Fehler:
      Schweregrad Code Beschreibung Projekt Datei Zeile Unterdrückungszustand
      Fehler Die Ressourcendatei "My Project\Form3.resx" wurde nicht gefunden. Tea Timer Professional


      Nach Doppelklick passiert ebenfalls nix.

      Edit:
      Zu dem anderen mach ich mir mal Gedanken und schreibe dir dann mal einen Vorschlagcodeablauf in "Klartext", denn ich bin mir nicht sicher, ob ich das korrekt verstanden habe.
      Der Grund warum ein Wert in der LabelTemperatur angezeigt werden soll, wenn kein Eintrag in der Binding Source existiert ist, dass ich die Temperatur ja auch einstellen können muss, wenn etwas ausgewhält ist, oder wenn eben nichts in der Binding Source existiert.

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

      DerSmurf schrieb:

      Fehler Für "My Project\Form3.resx" kann kein Manifestressourcenname erstellt werden
      Da könnte in der vbproj-Datei noch einVerweis liegen. Entweder Visual Studio beenden und die vbproj-Datei in notepad öffnen und da nach Form3 suchen oder im Projektexplorer Rechtsklick auf Dein Projekt (nicht ganz oben auf die Projektmappe!), dann auf Entladen und dann nochmal Rechtsklick -> Datei.vbproj bearbeiten und dort eben nach Form3 suchen.
      Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

      Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
      Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.
      Ok, super, das werde ich heute Abend ausprobieren,

      Zur Klassenvariablen "Temperatur".
      Ich spreche mal meine Gedanken ab, bevor ich den Code umstrukturiere, und dann waren meine Gedanken mist :)

      Also ich erstelle erine Private Klassenvariable für die Temperatur (die Propertys würde ich mir sparen und sie direkt zuweisen, oder sollte ich niemals Klassenvariablen direkt zuweisen?).
      Das Binding zum Label Temperatur entferne ich.
      Dann erstelle ich eine "Datagridview_ClicK" Sub:
      Hier wird diese Variable gefüllt, das Label Temperatur aus der Variable gefüllt und die Sub zum anzeigen der entsprechenden Abkühlzeit wird aufgerufen, diesmal dann aber mit meiner Klassenvariablen als Parameter.
      Und meine beiden Temperatur plus und minus Buttons füttere ich ebenfalls mit der Klassenvariablen und erhöhe, bzw. verringere dann diese.
      Variable in Textbox und Sub zum anzeigen der Abkühlzeit feuern.

      Meinst du das so?
      Und könntest du mir dann verraten, wie ich am einfachsten eine bestimmte Spalte aus dem Gridview filtern kann?

      Edit:
      und warum ist es unsauber, die Temperatur aus dem Label zu ziehen, wenn dieses doch an die Binding Source geknüpft ist?
      Ja, das macht wohl Sinn. Ok.
      So, ich habe mit Vaporized Hilfe nun die Verweise auf Form3 gefunden, das Projekt läuft wieder.
      Den Datentyp von "Intervall" habe ich in My Settings auf Integer geändert. Keine Ahnung wie ich auf den Trichter gekommen bin, dass das ein Decimal sein muss.
      Nun sind aber alle Werte "von Natur aus" Integer und ich konvertiere garnüscht mehr.

      Die Klassen habe ich alle umbenannt - heißen jetzt alle so, wie die entsprechenden .vb Dateien und die Namen sind etaws logischer.
      Aslo die Klasse der Hauptform heißt nicht mehr fEinstellungen, sondern frmHauptform.

      Nun erstelle ich ein Backup und mache mich an das LabelTemperatur Problem.

      @VaporiZed aber eins verstehe ich nicht.
      Du schlägst vor, dass ich Temperatur als Klassenvariable deklariere und aufhöre die Daten aus dem Label zu ziehen.
      Das verstehe ich, damit ich Code und Layout voneinander trenne und wie Akanel oben schreibt, das Label eben nur zum anzeigen nutze, nicht zum speichern.
      Dann sagst du aber:
      Wenn Du ein sinnvolles Binding hast, brauchst Du Temperatur als (Klassen-)Variable überhaupt nicht mehr.

      Das verstehe ich nicht.

      Edit:
      So ich habe meinen Code jetzt umstrukturiert und das Datenpuhlen aus dem Label Temperatur entfernt.
      Hierzu habe ich dann auch die entsprechende Binding Source dieses Labels entfernt.
      Bei der Überarbeitung ist mir dann aber aufgefallen, dass ich ja auch mit den Werten aus den Labels ZiehzeitSekunden und -Minuten rechne.
      Dies habe ich dann ebenfalls unterbunden.
      Hier noch ein Hinweis: Ich möchte auch Ziehzeit und Temperatur ändern können, wenn kein Tee im Datagridview ausgewählt ist und auch, wenn im Gridview zum Beispiel Ziehzeit 2 Min gespeichert ist, soll diese (und natürlich auch die anderen Werte) vr dem Start änderbar sein.

      Der Code sieht nun wie folgt aus (edit2: ich habe das Projekt an diesen Post nochmal angehangen, dann könnt ihr entscheiden, wo ihr den Code sehen wollt, finds bei der Länge sehr unübersichtlich, wenns nich bunt ist)
      Spoiler anzeigen

      Quellcode

      1. Imports System.IO
      2. Imports Tea_Timer_Professional.DataSet1
      3. Public Class frmHauptform
      4. Private Temperatur As Integer = 100
      5. Private Sekunden As Integer = 0
      6. Private Minuten As Integer = 0
      7. Private _DataFile As New FileInfo("Tee.Xml")
      8. 'Form Close und Load Event
      9. Private Sub frmHauptform_Load(sender As Object, e As EventArgs) Handles MyBase.Load
      10. lblTemperatur.Text = Temperatur.ToString
      11. lblZiehzeitSekunden.Text = Sekunden.ToString("00")
      12. lblZiehzeitMinuten.Text = Minuten.ToString("00")
      13. DataSet1.ReadXml(_DataFile.FullName)
      14. End Sub
      15. Private Sub frmHauptform_FormClosed(sender As Object, e As FormClosedEventArgs) Handles MyBase.FormClosed
      16. DataSet1.WriteXml(_DataFile.FullName)
      17. End Sub
      18. 'Klick Events - Buttons
      19. Private Sub btnTemperaturMinus_Click(sender As Object, e As EventArgs) Handles btnTemperaturMinus.Click
      20. 'verringert Temperatur um 5°
      21. Temperaturaendern(-5)
      22. End Sub
      23. Private Sub btnTemperaturPlus_Click(sender As Object, e As EventArgs) Handles btnTemperaturPlus.Click
      24. 'erhöht Temperatur um 5°
      25. Temperaturaendern(5)
      26. End Sub
      27. Private Sub btnZiehzeitPlus_Click(sender As Object, e As EventArgs) Handles btnZiehzeitPlus.Click
      28. 'Ziehzeit erhöhen
      29. Ziehzeitaendern("+")
      30. End Sub
      31. Private Sub btnZiehzeitMinus_Click(sender As Object, e As EventArgs) Handles btnZiehzeitMinus.Click
      32. 'Ziehzeit verkürzen
      33. Ziehzeitaendern("-")
      34. End Sub
      35. Private Sub btnstart_Click(sender As Object, e As EventArgs) Handles btnstart.Click
      36. 'Sub zum starten des Timers
      37. 'prüfen ob Ton agespielt werden soll
      38. Dim Sound As Boolean = My.Settings.Sound
      39. 'Ziehzeit in Sekunden umrechnen
      40. Dim Ziehzeit As Integer = Sekunden + Minuten * 60
      41. 'wenn keine Zeit vergeben wurde, abbruch der Sub
      42. If Ziehzeit = 0 Then
      43. MessageBox.Show("Bitte Ziehzeit eingeben.")
      44. Exit Sub
      45. End If
      46. 'Temperaturzeit in Sekunden umrechnen
      47. Dim AbkuehlSekunden As Integer = Integer.Parse(lblAbkuehlzeitSekunden.Text)
      48. Dim AbkuehlMinuten As Integer = Integer.Parse(lblAbkuehlzeitMinuten.Text)
      49. Dim Abkuehlzeit As Integer = AbkuehlSekunden + AbkuehlMinuten * 60
      50. 'aktuelle Form ausblenden
      51. Me.Hide()
      52. 'Wenn Abkühlzeit größer als 0, dann zeigen der Form fTimer Abkühlen
      53. If Abkuehlzeit > 0 Then
      54. Dim frmAbkuehlzeit As New frmTimer
      55. With frmAbkuehlzeit
      56. .SetSound = Sound
      57. .SetZeit = Abkuehlzeit
      58. .SetZiehen = False
      59. .ShowDialog(Me)
      60. End With
      61. End If
      62. 'zeigen der Form fTimer für die Ziehzeit
      63. Dim frmZiehzeit As New frmTimer
      64. With frmZiehzeit
      65. .SetSound = Sound
      66. .SetZeit = Ziehzeit
      67. .SetZiehen = True
      68. .ShowDialog(Me)
      69. End With
      70. Me.Show()
      71. End Sub
      72. Private Sub btnbeenden_Click(sender As Object, e As EventArgs) Handles btnbeenden.Click
      73. 'Sub zum beenden des Programms
      74. Me.Close()
      75. End Sub
      76. Private Sub btnloeschen_Click_1(sender As Object, e As EventArgs) Handles btnloeschen.Click
      77. 'Sub zum löschen aus dem Dataset
      78. DTTeesortenBindingSource.RemoveCurrent()
      79. End Sub
      80. Private Sub btnNeu_Click(sender As Object, e As EventArgs) Handles btnNeu.Click
      81. 'Sub zum Eintragen eines neuen Tees
      82. DTTeesortenBindingSource.EditNew(Of frmNeu)
      83. End Sub
      84. Private Sub DTTeesortenDataGridView_CellContentClick(sender As Object, e As DataGridViewCellEventArgs) Handles DTTeesortenDataGridView.CellContentClick
      85. Dim Spalte = DirectCast(DirectCast(DTTeesortenBindingSource.Current, DataRowView).Row, DTTeesortenRow)
      86. Temperatur = Spalte.Temperatur
      87. Sekunden = Spalte.Sekunden
      88. Minuten = Spalte.Minuten
      89. lblTemperatur.Text = Temperatur.ToString
      90. lblZiehzeitSekunden.Text = Sekunden.ToString("00")
      91. lblZiehzeitMinuten.Text = Minuten.ToString("00")
      92. TemperaturinZeit()
      93. End Sub
      94. Private Sub DTTeesortenDataGridView_CellContentDoubleClick(sender As Object, e As DataGridViewCellEventArgs) Handles DTTeesortenDataGridView.CellContentDoubleClick
      95. 'Sub zum bearbeiten eines Tees
      96. DTTeesortenBindingSource.EditCurrent(Of frmNeu)
      97. End Sub
      98. 'Klick Events - MenuStrip1
      99. Private Sub BeendenToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles BeendenToolStripMenuItem.Click
      100. Me.Close()
      101. End Sub
      102. Private Sub EinstellungenToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles EinstellungenToolStripMenuItem.Click
      103. Dim frmEinstellungen As New frmEinstellungen
      104. frmEinstellungen.Show(Me)
      105. End Sub
      106. 'Subs und Funktionen
      107. Private Sub Temperaturaendern(Grad As Integer)
      108. 'Sub zum ändern der Temperatur
      109. Temperatur = Temperatur + Grad
      110. If Temperatur > 100 Then
      111. Temperatur = 100
      112. Exit Sub
      113. End If
      114. If Temperatur < 60 Then
      115. Temperatur = 60
      116. Exit Sub
      117. End If
      118. lblTemperatur.Text = Temperatur.ToString
      119. TemperaturinZeit()
      120. End Sub
      121. Private Sub Ziehzeitaendern(op As String)
      122. 'Intervall aus den Einstellungen lesen
      123. Dim Intervall As Integer = My.Settings.Zeitintervall
      124. If op = "+" Then
      125. 'Sekunden erhöhen
      126. Sekunden = Sekunden + Intervall
      127. 'wenn Sekunden >= 60, dann Sekunden -60 und Minuten +1
      128. If Sekunden >= 60 Then
      129. Sekunden = Sekunden - 60
      130. Minuten = Minuten + 1
      131. End If
      132. Else
      133. 'Sekunden verringern
      134. 'Abbruch, wenn Minuten und Sekunden auf 0 stehen
      135. If Minuten = 0 AndAlso Sekunden = 0 Then Exit Sub
      136. Sekunden = Sekunden - Intervall
      137. 'wenn Sekunden < 0, dann Sekunden +60 und Minuten -1
      138. If Sekunden < 0 Then
      139. Sekunden = Sekunden + 60
      140. Minuten = Minuten - 1
      141. End If
      142. End If
      143. lblZiehzeitMinuten.Text = Minuten.ToString("00")
      144. lblZiehzeitSekunden.Text = Sekunden.ToString("00")
      145. End Sub
      146. Private Sub TemperaturinZeit()
      147. 'Sub zum ändern der Abkühlzeit je nach Temperatur
      148. Dim Zeit As Integer
      149. Select Case Temperatur
      150. Case = 100 : Zeit = 0
      151. Case = 95 : Zeit = (My.Settings.Temp95)
      152. Case = 90 : Zeit = (My.Settings.Temp90)
      153. Case = 85 : Zeit = (My.Settings.Temp85)
      154. Case = 80 : Zeit = (My.Settings.Temp80)
      155. Case = 75 : Zeit = (My.Settings.Temp75)
      156. Case = 70 : Zeit = (My.Settings.Temp70)
      157. Case = 65 : Zeit = (My.Settings.Temp65)
      158. Case 60 : Zeit = (My.Settings.Temp60)
      159. End Select
      160. lblAbkuehlzeitMinuten.Text = (Zeit \ 60).ToString("00")
      161. lblAbkuehlzeitSekunden.Text = (Zeit Mod 60).ToString("00")
      162. End Sub
      163. End Class


      Ich hoffe ich habe die Kritik hier nun richtig verstanden und das ganze gescheid umgesetzt.
      Nach der Überarbeitung stellen sich mir aber noch eine handvoll fragen.
      1. In der Button Start Sub greife ich noch auf 2 Labels zu, mit deren .Text ich arbeite:

      Quellcode

      1. 'Temperaturzeit in Sekunden umrechnen
      2. Dim AbkuehlSekunden As Integer = Integer.Parse(lblAbkuehlzeitSekunden.Text)
      3. Dim AbkuehlMinuten As Integer = Integer.Parse(lblAbkuehlzeitMinuten.Text)
      4. Dim Abkuehlzeit As Integer = AbkuehlSekunden + AbkuehlMinuten * 60
      5. 'aktuelle Form ausblenden
      6. Me.Hide()
      7. 'Wenn Abkühlzeit größer als 0, dann zeigen der Form fTimer Abkühlen
      8. If Abkuehlzeit > 0 Then
      9. Dim frmAbkuehlzeit As New frmTimer
      10. With frmAbkuehlzeit
      11. .SetSound = Sound
      12. .SetZeit = Abkuehlzeit
      13. .SetZiehen = False
      14. .ShowDialog(Me)
      15. End With
      16. End If
      17. 'zeigen der Form fTimer für die Ziehzeit
      18. Dim frmZiehzeit As New frmTimer
      19. With frmZiehzeit
      20. .SetSound = Sound
      21. .SetZeit = Ziehzeit
      22. .SetZiehen = True
      23. .ShowDialog(Me)
      24. End With
      25. Me.Show()

      Ist das ebenso schlimm, wie Die Labels Temperatur, ZiehzeitMinuten und -Sekunden waren? Oder darf man an dieser Stelle eine Ausnahme machen?

      2. Wie schlimm sind denn Klassenvariablen überhaupt? In VBA sollte ich immer versuchen diese zu vermeiden.
      Zwar hat man mir gesagt, dass es bei heutigen Rechnern, mit entsprechendem Ram nicht wirklich wichtig ist in einem VBA Programm auf Ressourcenschonung zu achten, allerdings gehöre es zum guten Ton unnötige globale Variablen zu vermeiden.
      Gilt das in gleichem Maße für VB.Net (z.B. im Fall von Frage1)

      3. Das holen der Daten aus der Binding Source. (betrifft das Tutorial von @ErfinderDesRades)
      Ich habe verstanden, dass ich die Daten aus der BindinSource holen soll und nicht aus der DataTable selber, denn die Binding Source stellt die Daten so bereit wie der Nutzer sie sieht (Filteurng, aktive Zeile, etc.)
      Dann habe ich es zwar geschafft den Beispielcode auf mein Projekt anzuwenden, aber ich verstehe ihn einfach nicht.
      Daher: hab ich es korekt gemacht? Oder geht das einfacher? Und könnte mir jemand den unten stehenden Code nochmal mit anderen Worten erklären?

      Quellcode

      1. Private Sub DTTeesortenDataGridView_CellContentClick(sender As Object, e As DataGridViewCellEventArgs) Handles DTTeesortenDataGridView.CellContentClick
      2. Dim Spalte = DirectCast(DirectCast(DTTeesortenBindingSource.Current, DataRowView).Row, DTTeesortenRow)
      3. Temperatur = Spalte.Temperatur
      4. Sekunden = Spalte.Sekunden
      5. Minuten = Spalte.Minuten

      Dieser Beitrag wurde bereits 7 mal editiert, zuletzt von „DerSmurf“ ()

      Das Projekt schaue ich mir ggf. morgen an, aber zu Deinen Punkten:
      "Wenn Du ein sinnvolles Binding hast, brauchst Du Temperatur als (Klassen-)Variable überhaupt nicht mehr."
      Binding bedeutet ja, dass z.B. das Label an den Wert einer Variablen gebunden ist. Das kann direkt sein, das kann über eine BindingSource gehen. Wenn es über eine BindingSource geht, ist das ja so bei Dir wahrscheinlich: Die BindingSource ist an eine DataTable eines tDS gebunden. Und in dem Label wird aus der entsprechenden DataTable der Wert jener Zeile angezeigt, die gerade in der BindingSoure als Current eingestellt ist. Dann brauchst Du keine Klassenvariable, denn der Wert ist ja in der DataTable-Zeile drin. Eine Klassenvariable wäre in dem Fall ein zusätzlicher Speicherplatz für denselben Wert. Und das wär ja redundant, also effektiv überflüssig.

      DerSmurf schrieb:

      In der Button Start Sub greife ich noch auf 2 Labels zu, mit deren .Text ich arbeite. [...] Ist das ebenso schlimm, wie Die Labels Temperatur, ZiehzeitMinuten und -Sekunden waren? Oder darf man an dieser Stelle eine Ausnahme machen?
      Schlimm: ja; Ausnahme: nie. Ganz krass ausgedrückt.
      Warum Du glaubst Ausnahmen zu brauchen, weiß ich ggf., wenn ich mir das Projekt angeschaut habe.

      DerSmurf schrieb:

      Wie schlimm sind denn Klassenvariablen überhaupt? In VBA sollte ich immer versuchen diese zu vermeiden. Zwar hat man mir gesagt, dass es bei heutigen Rechnern, mit entsprechendem Ram nicht wirklich wichtig ist in einem VBA Programm auf Ressourcenschonung zu achten, allerdings gehöre es zum guten Ton unnötige globale Variablen zu vermeiden. Gilt das in gleichem Maße für VB.Net (z.B. im Fall von Frage1)
      Globale Variablen gibt es in VB.Net nur mit Tricks. Und die sollte man vermeiden. Klassenvariablen hingegen sind nicht global, sondern nur in der Klasse verfügbar (solange sie nicht Public sind, und das sollten sie auch nie sein.) Und wenn die Klassen gut designt sind, dann sind Klassenvariablen auch absolut sinnvoll, ja sogar meist notwendig.

      DerSmurf schrieb:

      Ich habe verstanden, dass ich die Daten aus der BindinSource holen soll und nicht aus der DataTable
      Das ist situationsabhängig. Eine BindingSource kann filtern und sortieren. Oft verwende ich aber die DataTable-"Rohdaten", da käme mir die BindingSource eher in den Weg. Die aktive Zeile kannst Du aber nur sinnvollerweise aus der BindingSource holen. Entweder direkt oder mit ihrer Hilfe.

      Zu Deinem Codeposting ganz am Schluss: Dein Variablenname ist falsch. Dies ist keine Spalte, sondern eine Zeile. Und zwar die aktuell in der BindingSource selektierte Zeile. Da eine BindingSource an vieles gebunden sein kann, muss man, um typisiert arbeiten zu können, casten, da BindingSource.Current einen Wert vom allgemeinen Typ Object zurückgibt. Wenn eine BindingSource an eine DataTable eines tDS gebunden ist, gibt BindingSource.Current aber keine DataRow wieder, sondern ein DataRowView. Da steckt mehr als nur die Row selber dahinter. Einfach mal nen Haltepunkt setzen und reinschauen, was alles. Man castet also Current vom Typ Object in ein DataRowView (innerer Cast). Von dem DataRowView nimmt man dann die Row her. Dann hat man ne DataRow. Aber eine untypisierte, also allgemeine. Von der kannst Du z.B. nicht .Temperatur abfragen. Und daher castet man nochmal und wandelt die allgemeine DataRow in (D)eine typisierte DataRow, also eine DTTeesortenRow um. Und dann kannst Du .Temperatur abfragen, weil DTTeesortenRow eben eine Temperatur kennt.
      Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

      Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
      Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.
      Huhu.
      Jetzt kommt bei mir ein wenig Licht ins dunkle :)
      danke für deine Ausführung.

      Also wäre die Klassenvariable Temperatur überflüssig, wenn ich diese nur aus meinem Dataset fülle.
      Da dies ja bei mir nicht der Fall ist(+ und - Buttons), hab ich glaube ich alles richtig gemacht. Mal abwarten...

      Dann werde ich aber denke ich die beiden angesprochenen .Text Zugriffe auch noch abändern müsssen.
      Hier meinte ich eine Ausnahme machen zu können, weil ich, wenn ich diesen einen einzigen Zugriff auf die beiden Labels unterbinde, eben noch zwei weitere Klassenvariablen benötige.
      Aber ich denke ich mache nichts falsch, wenn ich mich für den Anfang daran halte, dass Labelname.text nur auf der rechten Seite des Gleichheitszeichen steht.

      Eine Frage habe ich aber noch vergessen.
      In meinem Code sind nun drei Klassenvariablen (Public Name as wasauchimmer = wert).
      Hierfür habe ich nun keine Property (set und get), sondern ich greife direkt darauf zu.
      Ist das soweit in Ordnung? Hauptsache sie sind private?

      So, nun warte ich gespannt auf Kritik v 2.0

      edit:Bitte entschuldige, aber ich habe gerade erst gesehen, dass ich mir mein Datagridview zerschossen habe.
      Ich musste die Spaltennamen umbenennen. Diese hießen nur "Name" "Minuten" "Sekunden" usw., das ist dann aber mit meinen Klassenvariablen "Minuten" und "Sekunden" kollidiert.
      Daher habe ich die Spalten entsprechend in "clmMinuten" usw. umbenannt. Dabei ist mir aber irgendwie die Formatierung gestorbenund ich habe versehentlich die Spalten der BindingSource umbenannt.
      Hier habe ich das Projekt jetzt mit funktionierendem Datagridview neu hochgeladen (und der Default Value für "Minuten" im Dataset ist jetzt 0, weil ich in einen Fehler renne, wenn bei einem neuen Eintrag keine Zeit festgelegt wird (Wert war vorher "").
      Ich habe aber natürlich keine Änderung am Code mehr vorgenomen.
      Dateien
      • tea timer.zip

        (2,83 MB, 8 mal heruntergeladen, zuletzt: )

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

      Das Programm ist jetzt nicht sooo intuitiv. Was ich in den Nebenforms mache, ist mir klar. Aber im Hauptform?
      Das mit Ziehzeit und Abkühlzeit ist für Dich sicher logisch. Aber insofern nicht ganz praxisnah, da das sehr von Material und Menge abhängt. Einen Tropfen Wasser von 100 °C auf 90 °C zu bringen dauert wahrscheinlich nicht ganz so lange wie bei einer Tasse oder einem Liter. Ok, der Tropfen ist auch nicht realitätsnah. Aber wenn ich ne Familienkanne machen will?

      Warum kann ich bei [neu] als Zeit 1 Minute 60 Sekunden einstellen?

      Das mit dem aus-den-Labels-Werte-rauspuhlen:
      Du kannst es entweder mit einem Array, mit einer weiteren Tabelle im tDS oder einer einfachen Funktion umgehen, denn alles, was Du machst, ist: Temperatur in Zeit umwandeln. Obwohl das beim Hinschreiben schon so komisch klingt, wie es ist.
      Mit der zusätzlichen DataTable ersparst Du Dir all Deine Temperatursettings und eine Funktion. In die Tabelle schreibst Du nur die Werte rein, die Du in der Sub TemperaturinZeit schon drinstehen hast und kannst so ggf. die Labels binden oder zumindest mit Daten befüllen und gleichzeitig an anderer Stelle (in btnstart_Click) Deine Berechnungen durchführen.

      Private Sub Ziehzeitaendern(op As String) Du übergibst nen String und wertest diesen aus? Stichwort Pfeil-Rücken-Brust-Auge

      Wie - glaube ich - schonmal geschrieben Temperatur = Temperatur + Grad -> Temperatur += Grad

      Die Sub Temperaturaendern ist etwas zu umständlich. Sinnvoller wäre sowas:

      VB.NET-Quellcode

      1. Private Sub Temperaturaendern(Grad As Integer)
      2. 'Sub zum ändern der Temperatur
      3. Dim NeueTemperatur = Temperatur + Grad
      4. If NeueTemperatur > 100 OrElse NeueTemperatur < 60 Then Exit Sub
      5. Temperatur = NeueTemperatur
      6. lblTemperatur.Text = Temperatur.ToString
      7. TemperaturinZeit()
      8. End Sub


      In fTimer_Load: If Ziehen = True Then -> If Ziehen Then
      Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

      Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
      Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.

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