Visual Basic-引发事件

时间:2019-05-17 04:51:08

标签: vb.net

我正在做一个想让我举起并发出事件警报的任务。详细信息如下。

在第4章的末尾执行练习4.1至4.3,如下所示。您将需要提交两个版本的代码,一个带有静态事件处理程序,另一个带有动态事件处理:

4.1使用第3章练习中的Car代码类,添加声明并引发一个名为LowGas的事件的代码。气体含量达到或低于5时会引发此事件。

4.2在表单方面,添加代码,以便在引发LowGas事件时,通过要求用户使用静态事件处理来抽气来处理该事件。

4.3要练习动态事件处理,请使用动态事件处理实现LowGas事件的处理。确保正确删除处理程序。

我已经尝试过多次阅读教科书,但是我仍然对这份作业感到迷茫。

Public Class Car
    'Properties of car
    Private VINNumber As Integer
    Private mGasLevel As Double
    Private mMileage As Double
    Private mMPG As Double
    Event gasAlert()
    Private messageLog As String

    Public ReadOnly Property GasLevel() As Double
        Get
            Return mGasLevel
    End Get
End Property

Public ReadOnly Property MPG() As Double
    Get
        Return mMPG
    End Get
End Property

Public Property Mileage() As Double
    Get
        Return mMileage
    End Get
    Set(value As Double)
        mMileage = value
    End Set
End Property

'method pump-gas to pump gas into the car
Public Sub PumpGas(gallons As Double)
    mGasLevel = mGasLevel + gallons
    'TextBox3.Text = c.GasLevel

End Sub

'method drive to drive the car
Public Sub Drive(driven As Double)

    Dim drive As Double
    Dim ableToDrive As Double
    messageLog = ""

    If driven > 0 Then
        drive = driven
        ableToDrive = (GasLevel * MPG)

        If drive > ableToDrive Then
            messageLog = "Gas Level is too low it has only" & Format(GasLevel, "0.#") & " gallons in the tank, you wil be able" & vbNewLine & "to drive" & Format(ableToDrive, "0.#") & " miles. Please Pump Gas"
            mMileage = Mileage + drive
            mGasLevel = GasLevel - (drive / MPG)
        Else
            mMileage = Mileage + ableToDrive
            mGasLevel = GasLevel - (ableToDrive / MPG)
        End If

        If mGasLevel <= 5 Then
            messageLog = ""
            RaiseEvent gasAlert()
        End If

    End If
End Sub

'constructor to create class
Public Sub New(ByVal v As Integer, ByVal g As Double, ByVal m As Double, ByVal mp As Double)
    VINNumber = v
    mGasLevel = g
    mMileage = m
    mMPG = mp
End Sub

End Class

Public Class Form1

'initial form level parameters
Dim c As Car
Dim WithEvents eventCar As Car
Dim messageLog As String
Dim isCarCreated As Boolean

Public Sub New()
    InitializeComponent()
    Label5.Visible = False
End Sub

'method to create a new car
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    If TextBox1.Text <> String.Empty And TextBox2.Text <> String.Empty And TextBox3.Text <> String.Empty And TextBox4.Text <> String.Empty Then
        c = New Car(Convert.ToInt64(TextBox1.Text), Convert.ToDouble(TextBox3.Text), Convert.ToDouble(TextBox2.Text), Convert.ToDouble(TextBox4.Text))
        Label5.Visible = True
        Label5.Text = "New Car Created!!"
        isCarCreated = True
    Else
        MessageBox.Show("Make sure everything is filled out first.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error)

    End If

End Sub

'click method to call pump gas method and accept the gallons of gas
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
    Dim gallons As Double
    If c IsNot Nothing Then

        gallons = Convert.ToDouble(TextBox6.Text)
        c.PumpGas(gallons)
        TextBox3.Text = c.GasLevel
    Else
        MessageBox.Show("Create a car first before pumping gas.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error)

    End If
End Sub

'click method to call Drive method to drive the car
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click

    Dim driven As Double

    If c IsNot Nothing Then
        driven = Convert.ToDouble(TextBox5.Text)

        TextBox2.Text = c.Mileage
        TextBox3.Text = c.GasLevel
        AddHandler c.gasAlert, AddressOf gasAlertNotificationDynamic
        c.Drive(driven)
        RemoveHandler c.gasAlert, AddressOf gasAlertNotificationDynamic
    Else
        MessageBox.Show("Create a car first before driving.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error)
    End If

End Sub

Private Sub btnRemoveCar_Click(sender As Object, e As EventArgs) Handles btnRemoveCar.Click
    If c IsNot Nothing Then
        c = Nothing
        Label5.Visible = False
        TextBox1.Text = String.Empty
        TextBox2.Text = String.Empty
        TextBox3.Text = String.Empty
        TextBox4.Text = String.Empty
        TextBox5.Text = String.Empty
        TextBox6.Text = String.Empty
    Else
        MessageBox.Show("There are no cars created.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error)

    End If
End Sub
Sub gasAlertNotificationStatic() Handles eventCar.gasAlert
    MessageBox.Show("Only " & Format(c.GasLevel, "#.#") & " gallons left.", "Gas Alert _ static", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
End Sub

Sub gasAlertNotificationDynamic()
    MessageBox.Show("Only " & Format(c.GasLevel, "#.#") & " gallons left.", "Gas Alert _ dynamic", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
End Sub
End Class

当我运行该应用程序,创建一辆汽车并尝试开车时,只有当我的汽油量为5加仑或更少时,警报才会触发。

1 个答案:

答案 0 :(得分:0)

您的问题似乎在Public Sub Drive(driven As Double)方法中。要进入RaiseEvent gasAlert(),调用代码需要进入If mGasLevel <= 5 Then。这意味着If driven > 0 Then成功。我会在该行上设置一个断点,观察您逐步执行每行时会发生什么。您尚未给我们提供开始的条件,所以这对于您的状况我是最好的。

只是为了给您更多帮助,我已经重构了您的代码。我希望这会有所帮助:

Public Class Form1
    Private WithEvents _car As Car

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Me.UpdateUI(String.Empty)
    End Sub

    Private Function ParseNullableInteger(text As String) As Integer?
        Dim result As Integer? = Nothing
        Dim x As Integer
        If (Integer.TryParse(text, x)) Then
            result = x
        End If
        Return result
    End Function

    Private Function ParseNullableDouble(text As String) As Double?
        Dim result As Double? = Nothing
        Dim x As Double
        If (Double.TryParse(text, x)) Then
            result = x
        End If
        Return result
    End Function

    Private Sub ButtonCreateCar_Click(sender As Object, e As EventArgs) Handles ButtonCreateCar.Click
        Dim vinNumber = ParseNullableInteger(TextBoxVinNumber.Text)
        Dim gasLevel = ParseNullableDouble(TextBoxGasLevel.Text)
        Dim mpg = ParseNullableDouble(TextBoxMpg.Text)
        If vinNumber.HasValue AndAlso gasLevel.HasValue AndAlso mpg.HasValue Then
            _car = New Car(vinNumber.Value, gasLevel.Value, mpg.Value)
            UpdateUI("New Car Created!!")
        Else
            MessageBox.Show("Make sure everything is filled out first.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error)
        End If
    End Sub

    Private Sub ButtonPumpGas_Click(sender As Object, e As EventArgs) Handles ButtonPumpGas.Click
        If _car IsNot Nothing Then
            Dim gallons = ParseNullableDouble(TextBoxGallons.Text)
            If gallons.HasValue Then
                _car.PumpGas(gallons)
            Else
                MessageBox.Show("Enter gallons correctly.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error)
            End If
        Else
            MessageBox.Show("Create a car first before pumping gas.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error)
        End If
    End Sub

    Private Sub ButtonDrive_Click(sender As Object, e As EventArgs) Handles ButtonDrive.Click
        If _car IsNot Nothing Then
            Dim driven = ParseNullableDouble(TextBoxDriven.Text)
            If driven.HasValue Then
                AddHandler _car.LowGas, AddressOf LowGasHandlerDynamic
                _car.Drive(driven)
                RemoveHandler _car.LowGas, AddressOf LowGasHandlerDynamic
            Else
                MessageBox.Show("Enter driven correctly.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error)
            End If
        Else
            MessageBox.Show("Create a car first before driving.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error)
        End If
    End Sub

    Private Sub ButtonRemoveCar_Click(sender As Object, e As EventArgs) Handles ButtonRemoveCar.Click
        If _car IsNot Nothing Then
            _car = Nothing
            Me.UpdateUI(String.Empty)
        Else
            MessageBox.Show("There are no cars created.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error)
        End If
    End Sub

    Private Sub UpdateUI(message As String)
        If Not String.IsNullOrEmpty(message) Then
            Me.LabelMessage.Visible = True
            Me.LabelMessage.Text = message
        Else
            Me.LabelMessage.Visible = False
        End If
        Me.TextBoxVinNumber.Enabled = _car Is Nothing
        Me.TextBoxMpg.Enabled = _car Is Nothing
        Me.TextBoxGasLevel.Enabled = _car Is Nothing
        Me.TextBoxDriven.Enabled = _car IsNot Nothing
        Me.TextBoxGallons.Enabled = _car IsNot Nothing
        If _car IsNot Nothing Then
            Me.TextBoxMileage.Text = _car.Mileage
            Me.TextBoxGasLevel.Text = _car.GasLevel
        Else
            Me.TextBoxVinNumber.Text = String.Empty
            Me.TextBoxMileage.Text = String.Empty
            Me.TextBoxGasLevel.Text = String.Empty
            Me.TextBoxMpg.Text = String.Empty
            Me.TextBoxDriven.Text = String.Empty
            Me.TextBoxGallons.Text = String.Empty
        End If
        Me.TextBoxMileage.Enabled = False
    End Sub

    Private Sub CarDrivenOrPumped(sender As Object, args As EventArgs) Handles _car.CarDriven, _car.CarPumped
        Me.UpdateUI(String.Empty)
    End Sub

    Private Sub LowGasHandlerStatic(sender As Object, args As EventArgs) Handles _car.LowGas
        MessageBox.Show("Only " & Format(_car.GasLevel, "0.0") & " gallons left.", "Gas Alert _ static", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
    End Sub

    Private Sub LowGasHandlerDynamic(sender As Object, args As EventArgs)
        MessageBox.Show("Only " & Format(_car.GasLevel, "0.0") & " gallons left.", "Gas Alert _ dynamic", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
    End Sub
End Class

Public Class Car
    Public Event LowGas As EventHandler
    Public Event CarDriven As EventHandler
    Public Event CarPumped As EventHandler

    Public Sub New(ByVal vinNumber As Integer, ByVal gasLevel As Double, ByVal mpg As Double)
        Me.VinNumber = vinNumber
        Me.GasLevel = gasLevel
        Me.Mpg = mpg
    End Sub

    Private _gasLevel As Double = 0.0

    Public Property GasLevel() As Double
        Get
            Return _gasLevel
        End Get
        Private Set(value As Double)
            _gasLevel = value
            If _gasLevel <= 5 Then
                RaiseEvent LowGas(Me, EventArgs.Empty)
            End If
        End Set
    End Property

    Public ReadOnly Property VinNumber() As Double
    Public ReadOnly Property Mpg() As Double
    Public ReadOnly Property Mileage() As Double
        Get
            Return Me.Mpg * Me.GasLevel
        End Get
    End Property

    Public Sub PumpGas(gallons As Double)
        Me.GasLevel += gallons
        RaiseEvent CarPumped(Me, EventArgs.Empty)
    End Sub

    Public Sub Drive(driven As Double)
        Dim actually = Math.Min(driven, Me.Mileage)
        If actually > 0 Then
            Me.GasLevel -= actually / Me.Mpg
            RaiseEvent CarDriven(Me, EventArgs.Empty)
        End If
    End Sub
End Class

或更简化的Form1版本:

Public Class Form1
    Private WithEvents _car As Car

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Me.UpdateUI(String.Empty)
    End Sub

    Private Function ParseNullableInteger(text As String) As Integer?
        Dim result As Integer? = Nothing
        Dim x As Integer
        If (Integer.TryParse(text, x)) Then
            result = x
        End If
        Return result
    End Function

    Private Function ParseNullableDouble(text As String) As Double?
        Dim result As Double? = Nothing
        Dim x As Double
        If (Double.TryParse(text, x)) Then
            result = x
        End If
        Return result
    End Function

    Private Sub ButtonCreateCar_Click(sender As Object, e As EventArgs) Handles ButtonCreateCar.Click
        Dim vinNumber = ParseNullableInteger(TextBoxVinNumber.Text)
        Dim gasLevel = ParseNullableDouble(TextBoxGasLevel.Text)
        Dim mpg = ParseNullableDouble(TextBoxMpg.Text)
        If vinNumber.HasValue AndAlso gasLevel.HasValue AndAlso mpg.HasValue Then
            _car = New Car(vinNumber.Value, gasLevel.Value, mpg.Value)
            UpdateUI("New Car Created!!")
        Else
            MessageBox.Show("Make sure everything is filled out first.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error)
        End If
    End Sub

    Private Sub ButtonPumpGas_Click(sender As Object, e As EventArgs) Handles ButtonPumpGas.Click
        Dim gallons = ParseNullableDouble(TextBoxGallons.Text)
        If gallons.HasValue Then
            _car.PumpGas(gallons)
        Else
            MessageBox.Show("Enter gallons correctly.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error)
        End If
    End Sub

    Private Sub ButtonDrive_Click(sender As Object, e As EventArgs) Handles ButtonDrive.Click
        Dim driven = ParseNullableDouble(TextBoxDriven.Text)
        If driven.HasValue Then
            AddHandler _car.LowGas, AddressOf LowGasHandlerDynamic
            _car.Drive(driven)
            RemoveHandler _car.LowGas, AddressOf LowGasHandlerDynamic
        Else
            MessageBox.Show("Enter driven correctly.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error)
        End If
    End Sub

    Private Sub ButtonRemoveCar_Click(sender As Object, e As EventArgs) Handles ButtonRemoveCar.Click
        _car = Nothing
        Me.UpdateUI(String.Empty)
    End Sub

    Private Sub UpdateUI(message As String)
        If Not String.IsNullOrEmpty(message) Then
            Me.LabelMessage.Visible = True
            Me.LabelMessage.Text = message
        Else
            Me.LabelMessage.Visible = False
        End If
        Me.UpdateUI()
    End Sub

    Private Sub UpdateUI()
        Me.ButtonCreateCar.Enabled = _car Is Nothing
        Me.ButtonDrive.Enabled = _car IsNot Nothing
        Me.ButtonPumpGas.Enabled = _car IsNot Nothing
        Me.ButtonRemoveCar.Enabled = _car IsNot Nothing
        Me.TextBoxVinNumber.Enabled = _car Is Nothing
        Me.TextBoxMpg.Enabled = _car Is Nothing
        Me.TextBoxGasLevel.Enabled = _car Is Nothing
        Me.TextBoxDriven.Enabled = _car IsNot Nothing
        Me.TextBoxGallons.Enabled = _car IsNot Nothing
        If _car IsNot Nothing Then
            Me.TextBoxMileage.Text = _car.Mileage
            Me.TextBoxGasLevel.Text = _car.GasLevel
        Else
            Me.TextBoxVinNumber.Text = String.Empty
            Me.TextBoxMileage.Text = String.Empty
            Me.TextBoxGasLevel.Text = String.Empty
            Me.TextBoxMpg.Text = String.Empty
            Me.TextBoxDriven.Text = String.Empty
            Me.TextBoxGallons.Text = String.Empty
        End If
        Me.TextBoxMileage.Enabled = False
    End Sub

    Private Sub CarDrivenOrPumped(sender As Object, args As EventArgs) Handles _car.CarDriven, _car.CarPumped
        Me.UpdateUI()
    End Sub

    Private Sub LowGasHandlerStatic(sender As Object, args As EventArgs) Handles _car.LowGas
        MessageBox.Show("Only " & Format(_car.GasLevel, "0.0") & " gallons left.", "Gas Alert _ static", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
    End Sub

    Private Sub LowGasHandlerDynamic(sender As Object, args As EventArgs)
        MessageBox.Show("Only " & Format(_car.GasLevel, "0.0") & " gallons left.", "Gas Alert _ dynamic", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
    End Sub
End Class