VisualBasic Aufruf von einem Fenster zum anderen

fox40phil

Rear Admiral
Registriert
Okt. 2008
Beiträge
5.546
Mahlzeit!

Situation:
Ich möchte ein Temperaturumwandler programmieren, dies ist mir in einem Fenster schon gelungen.
Nun möchte ich aber, dass man auswählen kann, ob man "Celsius->Fahrenheit" oder "Fahrenheit->Celsius" berechnen will. Nach der Auswahl mithilfe eines RadioButton drückt man auf den Button "berechnen". Daraufhin soll ein kleineres neues Fenster geöffnet werden in dem man die Temperatur eingibt und in dem dann auch der umgewandelte Wert angezeigt wird.

Problem:
Ich weiß nicht genau wie ich die Verbindung der beiden Klassen(Form1 & Umwandeln) hinbekomme.
Ich dachte dabei an eine If-Bedingung in Form1 in der entschieden wird ob der RadioButton bei "Fahrenheit->Celsius" ausgewählt ist oder nicht, ist dem nicht so soll die andere Funktion aufgerufen werden, in der Celsius zu Fahrenheit berechnet wird.


aktueller Stand:


form1:
Code:
Public Class Form1

    Dim Celsius_berechnen As Celsius_form

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        If RadioButton1.Checked Then

            Celsius_berechnen.berechne_Fahrenheit()
        Else
            Celsius_berechnen.berechne_Celsius()
        End If

    End Sub
    '---------------------------------------------------------------------------------------------------------------
    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click

        'Beendet das Programm beim drücken des abbrechen Buttons
        Application.Exit()

    End Sub
    '---------------------------------------------------------------------------------------------------------------
    
End Class



TempUmwalndeln:
Code:
Public Class TempUmwandeln

    Public Sub berechne_Fahrenheit()

        'Variablendekleration
        Dim dCelsius As Double
        Dim dFahrenheit As Double
        '--------------------------------------

        'Initialisierung der Variablen
        dFahrenheit = CDbl(TextBox1.Text)

        'Berechnung
        dFahrenheit = ((dCelsius * 9) / 5) + 32

        'Ausgabe
        Label1.Text = "Fahrenheit"
        TextBox2.Text = dFahrenheit
        Label2.Text = "Celsius"

    End Sub

    Public Sub berechne_Celsius()

        'Variablendekleration
        Dim dCelsius As Double
        Dim dFahrenheit As Double
        '--------------------------------------

        'Initialisierung der Variablen
        dCelsius = CDbl(TextBox1.Text)

        'Berechnung
        dCelsius = (dFahrenheit - 32) * 5 / 9

        'Ausgabe
        Label1.Text = "Celsius"
        TextBox2.Text = dCelsius
        Label2.Text = "Fahrenheit"

    End Sub
End Class


Ich hoffe das Problem ist von mir deutlich und verständlich dargestellt.


MfG Phil

Anbei 2 Screenshots der Fenster:
 

Anhänge

  • Window1.jpg
    Window1.jpg
    40,5 KB · Aufrufe: 150
  • Window2_Celsius.jpg
    Window2_Celsius.jpg
    28,7 KB · Aufrufe: 118
Zunächst musst du das zweite Form initialisieren.
Wenn du es so wie jetzt machst klappt es zwar mit der Berechnung aber das zweite Form wirst du nicht sehen und auch nichts eingeben können.

Dim Celsius_berechnen As TempUmwandeln = New TempUmwandeln wäre der richtige Aufruf.

Du solltest vielleicht mit deinem Aufruf erstmal nur das Form2 erzeugen.
Die Anordnung der Steuerelemente machst du dann abhängig von der Auswahl auf dem Form1.
Und erst wenn der User dann auf dem Form2 eine Eingabe gemacht hat rufst du die Funktion auf.
 
Öhm, wieso denn überhaupt auf mehreren Formen?
Nimm doch Listboxen mit denen man das auswählen kann, dann kannst du die mit einem 2D-Array der Umrechnungen synchronisieren.
Hast dann nur 2 Listboxen, 2 Textboxen und einen Button.
 
hmm, oder kann man nicht verschiedene Ebenen auf einem Fenster haben? Ich weiß nicht, so in dem Stil wie ein Installationsvorgang.

Listboxen kenne ich leider noch noch nicht^^

@schmidmi, ich werds gleich mal testen.
Ergänzung ()

So die Initialisierung habe ich nun, aber der Fehler ist nicht behoben^^, das Programm stürzt wie gehabt ab. Es stürzt ab, wenn ich auf "auswahl" drücke!

Naja in der Form2 verändern sich ja die "Label"s je nach dem welchen RadioButton man gewählt hat.
 
hm kay und in wie weit ändert das was an meinem Problem? ^^

Grundsätzlich will ich ja verstehen wie ich etwas in eine neue "Form" übertrage etc., das ist ja auch das Hauptproblem bei der Sache, denke ich.


Edit: Das ist die Fehlermeldung:

Code:
Eine Ausnahme (erste Chance) des Typs "System.NullReferenceException" ist in Temperaturechner 2.exe aufgetreten.
Eine Ausnahme (erste Chance) des Typs "System.NullReferenceException" ist in Temperaturechner 2.exe aufgetreten.
Eine Ausnahme (erste Chance) des Typs "System.InvalidCastException" ist in Microsoft.VisualBasic.dll aufgetreten.
Eine Ausnahme (erste Chance) des Typs "System.InvalidCastException" ist in Microsoft.VisualBasic.dll aufgetreten.
 
Zuletzt bearbeitet:
Du hast mehrere Möglichkeiten.
Wenn du in der Klasse TempUmwandeln ein Variable mit Public deklarierst kannst du diese von Form1 aus ansprechen.

Beispiel:
PHP:
------------in Class TempUmwandeln-------------------------
Public aussehen As Integer

------------------in Class Form1----------------------------------
        If RadioButton1.Checked Then
            TempUmwandeln.aussehen = 1
            'Celsius_berechnen.berechne_Fahrenheit()
        Else
            TempUmwandeln.aussehen = 2
            'Celsius_berechnen.berechne_Celsius()
        End If
        TempUmwandeln.Show()


------------------in Class TempUmwandeln---------------
        If aussehen = 1 Then
            'entweder die Positionen der Steuerelemente anpassen
            ' oder die Steuerelemente erst zur Laufzeit erstellen
        End If
 
Oder einfach Radiobutton.Checked übergeben, wenn´s nur 2 Sachen sind.
Er muss aber wohl nach nach Kelvin umrechnen können.
Oder halt ein Button für alles, der rechnet dann für alles halt um.
Oder Radiobuttons oder Checkbuttons wie auch immer daneben und die dann nochmal durchgehen.
 
Hallo fox40phil,

als ich mir deinen Code angesehen habe, stellte ich erstmal fest:
Du verwendest die Methoden (z.B. berechne_Fahrenheit()) des Objekts (Celsius_form) ohne es vorher initialisiert zu haben, zumindest ist es nicht in dem Code von Dir sichtbar. An deiner Stelle würde ich folgende Zeile in das Form1_Load(sender As Object, e As EventArgs) aufnehmen:
Code:
Celsius_berechnen = New Celsius_form()

oder alternativ bei der Variablendeklaration den New Operator direkt aufrufen:

Code:
'statt:
Dim Celsius_berechnen As Celsius_form
' besser:
Dim Celsius_berechnen As New Celsius_form()

Damit könnte die "System.NullReferenceException" gelöst sein, weil diese immer dann ausgelöst wird, wenn das Objekt, was man gerade verwenden will, leer (bzw. Nothing) ist.

Desweiteren verstehe ich nicht, warum du eine Klasse Celsius_form verwendest, aber eine TempUmwandeln Klasse als 2. Code postest. Vielleicht nur ein Versehen...

Ebenso sehe ich, das du CDbl zur Konvertierung verwendest, ohne vorher zu prüfen, ob der Text in der TextBox auch in Double konvertiert werden kann. D.h. wenn du in die Textbox mal "abc" eingibst, wirst du mit sehr hoher Wahrscheinlichkeit eine InvalidCast Exception sehen.

Alternative:
Code:
If Not Double.TryParse(TextBox1.Text, dCelsius) Then
  MsgBox("Hey, bitte nur numerische Werte eingeben!")
  Return ' Beende die Methode, weil falsche Eingabe
End If

Hoffe das hilft dir ein wenig weiter...

Grüße Rossibaer
 
Zuletzt bearbeitet:
eine Form kann selbstverständlich eine andere Aufrufen. Das aufzurufende Fenster muss nur vom Typ Form sein - was es automatisch ist, wenn du es mit dem Visual-Studio-Designer erstellt hast.

Dabei gibt es 2 Möglichkeite:

1. Das neue Fenster wird aufgerufen und das "alte" Fenster bleibt voll bedienbar

2. Das neue Fenster wird aufgerufen und das "alte" ist gesperrt, sodass das neue erst geschlossen werden muss (wie auch immer), damit das alter wieder verfügbar ist.


ersteres lässt sich mit

NeueForm.Show()

realisieren

das Zweite mit
NeueForm.ShowDialog()

bei beiden Funktionen ist ein DialogResult auswertbar, welcher im Neuen Fenster beeinflusst werden sollte.


Siehe

Public Sub Show():
http://msdn.microsoft.com/en-us/library/system.windows.forms.control.show.aspx

Overloads Public Function ShowDialog() As DialogResult:
http://msdn.microsoft.com/en-us/library/system.windows.forms.form.showdialog(VS.71).aspx
 
ich habe jetzt mal die "If-Bedingung" von Rossibaer eingebaut, aber leider kommt immer noch der Fehler.

Und zwar, wenn ich die Auswahl auf Celsius lasse und dann auf "auswahl" drücke kommt die Meldung im Visual Studio und das Programm stürzt ab:
Code:
Eine Ausnahme (erste Chance) des Typs "System.InvalidCastException" ist in Microsoft.VisualBasic.dll aufgetreten.

und zwar immer an der folgenden Stelle in der Klasse TempUmwandeln ( ich hab sie im Verlauf mal umbenannt^^)

Code:
'Initialisierung der Variablen
dFahrenheit = CDbl(TextBox1.Text)


€dit: ich hab mal das Projekt zusammengefasst als Zip hoch geladen! Damit ihr auch mal direkt rein gucken könnt
 

Anhänge

  • Temperatur 2.zip
    207,5 KB · Aufrufe: 127
Zuletzt bearbeitet:
Hallo fox40phil,

als ich deine Änderungen im Quellcode angeschaut habe, musste ich erstmal schmunzeln. ;-)

Ich hatte geschrieben:

Ebenso sehe ich, das du CDbl zur Konvertierung verwendest, ohne vorher zu prüfen, ob der Text in der TextBox auch in Double konvertiert werden kann. D.h. wenn du in die Textbox mal "abc" eingibst, wirst du mit sehr hoher Wahrscheinlichkeit eine InvalidCast Exception sehen.

Also was ich sagen wollte, war, das du das CDbl() und die Initialisierung der Variablen weglässt und stattdessen einfach das Double.TryParse verwendest. Du musst nicht die Double Variablen initialisieren, weil dies Wertetypen sind. In VB und auch C# ist bei solchen Typen KEINE Initialiserung erforderlich, weil diese bereits automatisch während der Laufzeit initialisiert werden. Du kannst diese Variablen natürlich Initialisieren, aber die Prüfung, ob die Konvertierung überhaupt möglich ist, muss dann vor dem Initialisieren erfolgen.

Am besten eignet sich für das Konvertieren die TryParse Methode, weil diese bei ungültigen Eingaben entsprechend False zurückgibt und sollte die Konvertierung machbar sein, dann hat man auch schon die Konvertierung des Wertes vollzogen (siehe 2. Parameter der Methode)

Nun zum Ablauf deiner Konvertierung:
1. Initialisiere nicht die Double-Variablen mit CDbl().
2. Rufe Double.TryParse() auf um den Wert von der TextBox in Double zu konvertieren.

Viel Erfolg!
 
also ich hab jetzt einfach dCelsius = TextBox1.Text geschrieben, aber dennoch kommt der Fehler, wenn ich vom "Hauptmenü" auf das neue Fenster über den Button "auswahl" gehe:
Eine Ausnahme (erste Chance) des Typs "System.InvalidCastException" ist in Microsoft.VisualBasic.dll aufgetreten.

wenn ich dann auf Details gehe kommt folgendes:

{"Ungültige Konvertierung von der Zeichenfolge in Typ Double."}

dort kann ich dann auf ganz ganz viele Informationen zugreifen.

Des Weiteren kommt sofort beim Einfügen des Befehls "Double.TryParse()", hab dann noch probiert ob ich in die Klammer "Textbox.Text" einfügen, aber ändert nichts am Fehler.
Fehler bei der Überladungsauflösung, da keine zugreifbare "TryParse" diese Anzahl von Argumenten akzeptiert.
 
Zuletzt bearbeitet:
... OHNE WORTE ...

Code:
Public Class TempUmwandeln

    Public Sub berechne_Fahrenheit()

        'Variablendekleration
        Dim dCelsius As Double
        Dim dFahrenheit As Double
        '--------------------------------------

        'Initialisierung der Variablen
        If Not Double.TryParse(TextBox1.Text, dCelsius) Then
          MsgBox("Hey, bitte nur numerische Werte eingeben!")
          Return ' Beende die Methode, weil falsche Eingabe
        End If

        'Berechnung
        dFahrenheit = ((dCelsius * 9) / 5) + 32

        'Ausgabe
        Label1.Text = "Fahrenheit"
        TextBox2.Text = dFahrenheit
        Label2.Text = "Celsius"

    End Sub

    Public Sub berechne_Celsius()

        'Variablendekleration
        Dim dCelsius As Double
        Dim dFahrenheit As Double
        '--------------------------------------

        'Initialisierung der Variablen
        If Not Double.TryParse(TextBox1.Text, dFahrenheit) Then
          MsgBox("Hey, bitte nur numerische Werte eingeben!")
          Return ' Beende die Methode, weil falsche Eingabe
        End If

        'Berechnung
        dCelsius = (dFahrenheit - 32) * 5 / 9

        'Ausgabe
        Label1.Text = "Celsius"
        TextBox2.Text = dCelsius
        Label2.Text = "Fahrenheit"

    End Sub
End Class
 
Zuletzt bearbeitet:
sorry, bin neu in VB.NET!
Okay jetzt kackt das Programm nicht ab, aber nun komme ich nicht vom Hauptmenü in das Fenster wo ich den Wert berechne, weil er beim drücken des Buttons "auswahl" sagt das es keine nummerische Zahl ist, ich aber noch gar keine eingegeben habe.

=X


Code:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        If RadioButton1.Checked Then

            TemperaturRechner.berechne_Fahrenheit()

        Else
            TemperaturRechner.berechne_Celsius()
        End If

    End Sub

das ist mein Aufruf in der Hauptklasse/Hauptmenü
 
Code:
    Public Sub berechne_Fahrenheit()

        'Variablendekleration
        Dim dCelsius As Double
        Dim dFahrenheit As Double
        '--------------------------------------

        If TextBox1.Text = String.Empty Then Return
        
        'Initialisierung der Variablen
        If Not Double.TryParse(TextBox1.Text, dCelsius) Then
          MsgBox("Hey, bitte nur numerische Werte eingeben!")
          Return ' Beende die Methode, weil falsche Eingabe
        End If

        'Berechnung
        dFahrenheit = ((dCelsius * 9) / 5) + 32

        'Ausgabe
        Label1.Text = "Fahrenheit"
        TextBox2.Text = dFahrenheit
        Label2.Text = "Celsius"

    End Sub

die 2. Methode musst du dann ebenso anpassen/ergänzen.

PS: Wo wird das 2. Fenster erstellt (New Operator) und angezeigt?
 
Zuletzt bearbeitet:
ich hatte bei dem Post vom 20.11.2009, 10:03 Uhr einen .zip angehangen mit dem Projekt.

Code:
Public Class Form1

    Dim TemperaturRechner As New TempUmwandeln()

danach kommt der Code von meinem letzten Post!


jetzt habe ich "If TextBox1.Text = String.Empty Then Return" ergänzt und nun kommt auch nicht mehr die Meldung der anderen IF-Bedingung, aber es geht nicht weiter! Also er springt immer noch nicht in das andere Fenster.


Also irg.was stimmt da nicht, der soll ja erst zurückspringen, wenn man vllt was falsches eingegeben hat oder so. Aber er springt ja nicht mal in das 2. Fenster, wo man die Berechnung bzw. die Temperatur eingibt!


:(
 
Ok, ich sehe das Problem. in der Form1 Klasse willst du schlichtweg zuviele Dinge auf einmal machen.

Also, du hast einen Button1 der auf das Click Ereignis reagiert. In diesem Click Ereignis sollte eigentlich nur der Code enthalten sein, der das 2. Formular öffnet, z.B.:

Code:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
  Celsius_berechnen.ShowDialog()
End Sub

Das sollte ausreichen um deinen 2. Dialog sehen zu können. Nun zur Berechnung:
Wenn ich dich richtig verstehe, möchtest du im Form1 nur entscheiden ob jetzt Celsius oder Fahrenheit berechnet werden soll. Beim Öffnen des 2. Fensters muss also irgendwie diese Information weiter gegeben werden. Du hast dafür sehr verschiedene Möglichkeiten, die alle Vor- und Nachteile besitzen.

Ein möglicher Weg wäre es, wenn du eine Property und eine Variable, z.B. sTemperaturEinheit in die TempUmwandeln Klasse reinmachst:

Code:
Private sTemperaturEinheit As String
Public Property TemperaturEinheit As String
  Get
    Return sTemperaturEinheit
  End Get
  Set(value as String)
    sTemperaturEinheit = value
  End Set
End Property

Danach kannst du im Click Ereignishandler (Event) von Form1.Button1 diese Property vor dem Öffnen setzen, wie gerade die Radio Buttons stehen, z.B.:

Code:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
  If RadioButton1.Checked Then
    Celsius_berechnen.TemperaturEinheit = "Celsius"
  Else
    Celsius_berechnen.TemperaturEinheit = "Fahrenheit"
  End If
  Celsius_berechnen.ShowDialog()
End Sub

Soviel erstmal zum Übergeben von Information/Variablen an eine 2. Klasse (in deinem Fall an TempUmwandeln).

Weiter gehts:

1. berechne_Fahrenheit() darf nur dann aufgerufen werden, wenn sTemperaturEinheit = "Fahrenheit" ist.
2. berechne_Celsius() darf nur dann aufgerufen werden, wenn sTemperaturEinheit = "Celsius" ist.

Am einfachsten würde ich in der TempUmwandeln Form auf das Validated Ereignis von TextBox1 reagieren, ähnlich wie du das schon in Form1 für Button1 hast, d.h. den Quellcode von Form1.Button1_Click in die TempUmwandeln Klasse einfügen, das Event auf TextBox1.Validated ändern ("Handles Button1.Click" durch "Handles TextBox1.Validated" ersetzen). Jedoch statt die Radiobuttons in der If Bedingung solltest du nun die Variable sTemperaturEinheit mit "Celsius" bzw. "Fahrenheit" vergleichen und dann die Berechnung ausführen lassen. Das Validated Event wird ausgelöst, wenn du in der TextBox1 eine Zahl eingibst und dann mit dem Cursor die TextBox verläßt. Nun hoffe ich das das so ungefähr deine Probleme löst...

Hier noch der Code:

Code:
Private Sub TextBox1_Validated(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox1.Validated
  If sTemperaturEinheit = "Fahrenheit" Then
    berechne_Fahrenheit()
  Else
    berechne_Celsius()
  End If
End Sub

Viel Erfolg
 
Zuletzt bearbeitet:
okay das sieht schon mal sehr fein aus, jetzt kommt nur noch ein Fehler. Und zwar hast du mir gesagt, dass es einmal die Subroutine "Button1_Click" zum aufrufen des 2. Fensters und das noch mal eine Subroutine "Button1_Click" zur Festellung der Temperaturart gibt, und diese sind beide in der form1, deshalb zeigt er mir nen Fehler an :freaky: ^^

hoffe du weißt was ich mein:rolleyes:

Ach und danke für deine Bemühungen =)


€dit: So ich habe das jetzt mal zu einer Subroutine zusammengefasst und als erstes kommt der ShowDialog und dann die If-Bedingung.

Nun startet auch das 2. Fenster! =) juhu...

aber ich hatte mir vorgestellt, das man sobald man eine Temperatur eingibt sofort die Umwandlung statt findet. Muss man dafür noch einen Befehl hinzufügen?

Und die Label's sollen je nach dem, ob man Fahrenheit zu Celsius oder umgekehrt dem entsprechen heißen. Aber ich hab das Gefühl, dass die beiden Funktionen zur Berechnung gar nicht aufgerufen werden.

ich lade das Projekt noch mal hoch ;). Du kannst es ja mal bitte testen! ;)
 

Anhänge

  • Temperaturechner 2_2009_11_26.zip
    170,2 KB · Aufrufe: 117
Zuletzt bearbeitet:
Danach kannst du im Click Ereignishandler (Event) von Form1.Button1 diese Property vor dem Öffnen setzen, wie gerade die Radio Buttons stehen

Schau bitte nochmal genau in meinen letzten Post und kopiere nicht einfach den Code ohne vorher zu verstehen was wo passiert... Sorry, aber es wird langsam Zeit, das du anfängst die Flügel aus zu fahren und das Fliegen lernst, statt weiter auf dem Boden zu hocken. Sei kreativ, lies Tutorials/Bücher, frag Google. Das was ich dir gegeben habe, sind Denkanstöße und mögliche Lösungsansätze. Es war hoffentlich nicht in deinem Sinn, dass ich alle deine Probleme löse...

Also in diesem Sinne
viel Erfolg!

Grüße
Rossibaer
 
Zurück
Oben