初学者? - 多个自定义控件的事件处理

时间:2016-09-20 04:36:56

标签: vb.net events lambda event-handling

使用Windows窗体应用程序进行员工安排。我有一个带有几个FlowPanel的主窗体,每个窗口都有几个自定义控件实例。每个自定义控件都可以引发LMB点击和人民币点击事件。目前,流动面板中的控件采用二维数组。

如何识别单击了哪个自定义控件?

我已经查看了SO上的其他主题(我无法弄清楚如何引用这里,但是AddressOf with parameter)。

直到我自学使用lambdas(我无法开始工作,顺便说一句,但这是我能找到的唯一潜在解决方案),还有其他方法可以解决这个问题吗?

FWIW,如有必要,我可以重新编码自定义控件。

编辑: 这是自定义控件的代码:

`Public Class ShiftViewControl
Inherits UserControl

'Sub-class clsShiftViewData
Public Class ClsShiftViewData
    'clsShiftViewData private properties
    Private _employee As String = ""
    Private _job As String = ""
    Private _startDate As Date = New Date(1900, 1, 1, 0, 0, 0, 0)
    Private _endDate As Date = New Date(1900, 1, 1, 0, 0, 0, 0)
    Private _hours As Double = 0
    Private _request As Boolean = False
    Private _splitShift As Boolean = False
    Private _override As Boolean = False
    Private _notes As String = ""

    'clsShiftViewData class property statements
    Public Property Employee() As String
        Get
            Return _employee
        End Get
        Set(ByVal value As String)
            _employee = value
        End Set
    End Property
    Public Property Job() As String
        Get
            Return _job
        End Get
        Set(ByVal value As String)
            _job = value
        End Set
    End Property
    Public Property StartDate() As Date
        Get
            Return _startDate
        End Get
        Set(ByVal value As Date)
            _startDate = value
        End Set
    End Property
    Public Property EndDate() As Date
        Get
            Return _endDate
        End Get
        Set(ByVal value As Date)
            _endDate = value
        End Set
    End Property
    Public Property Hours() As Double
        Get
            Return _hours
        End Get
        Set(value As Double)
            _hours = value
        End Set
    End Property
    Public Property Request() As Boolean
        Get
            Return _request
        End Get
        Set(ByVal value As Boolean)
            _request = value
        End Set
    End Property
    Public Property SplitShift() As Boolean
        Get
            Return _splitShift
        End Get
        Set(ByVal value As Boolean)
            _splitShift = value
        End Set
    End Property
    Public Property Override() As Boolean
        Get
            Return _override
        End Get
        Set(ByVal value As Boolean)
            _override = value
        End Set
    End Property
    Public Property Notes() As String
        Get
            Return _notes
        End Get
        Set(ByVal value As String)
            _notes = value
        End Set
    End Property
End Class

Public Event LmbClicked(ByRef sender As Object, ByVal e As MouseEventArgs)
Public Event RmbClicked(ByRef sender As Object, ByVal e As MouseEventArgs)

Private _shiftViewData As New ClsShiftViewData

Private Sub HandleAllClicks(ByVal sender As Object, ByVal e As MouseEventArgs) Handles lblEmployee.MouseClick, lblJob.MouseClick, lblStartTime.MouseClick, _
                                                                lblEndTime.MouseClick, lblHours.MouseClick, _
                                                                lblRequest.MouseClick, lblNotes.MouseClick, Me.MouseClick, _
                                                                lblSplitShift.MouseClick, lblOverride.MouseClick
    If e.Button = Windows.Forms.MouseButtons.Right Then
        RaiseEvent RmbClicked(Me, e)
    Else
        RaiseEvent LmbClicked(Me, e)
    End If
End Sub



'MISC methods here

Public Sub PutData(ByVal svInfo As ClsShiftViewData)
    'Fill both _shiftViewData and corresponding form controls
    _shiftViewData = svInfo
    With _shiftViewData
        lblEmployee.Text = .Employee
        lblJob.Text = .Job
        lblStartTime.Text = .StartDate.ToShortTimeString
        lblEndTime.Text = .EndDate
        '...
        lblNotes.Text = .Notes
    End With

End Sub
Public Sub GetData(ByRef svInfo As ClsShiftViewData)
    With svInfo
        .Employee = _shiftViewData.Employee
        .Job = _shiftViewData.Job
        .StartDate = _shiftViewData.StartDate
        .EndDate = _shiftViewData.EndDate
        .Hours = _shiftViewData.Hours
        .Request = _shiftViewData.Request
        .Notes = _shiftViewData.Notes
    End With

End Sub


Private Sub ShiftViewControl_Load(sender As Object, e As EventArgs) Handles MyBase.Load

End Sub

结束班

这是我目前正在处理的代码:

`Imports ShiftBox    '  .dll includes custom control ShiftViewControl

” '注意:很多这段代码正在试验,仅供参考,我已经删除了一些代码来澄清 “

Public Class FrmShiftBoard     Public Sv(7,6)因为ShiftViewControl'数组最终将是动态的     Public WithEvents TempSvc As New ShiftViewControl

Public Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
    DebugMode = False
    Const rowcount As Integer = 7
    Const spacing As Integer = 15
    Const intSpace As Integer = 15
    Dim fp(rowcount) As FlowLayoutPanel
    Dim tempFillData As New ShiftBox.ShiftViewControl.ClsShiftViewData
    Dim col As Integer
    Dim row As Integer
    Dim locationPoint As New Point
    Dim newLocationPoint As New Point
    Dim tempPoint As New Point


    'Following  section is my newbie code to setup the form
    Me.Width = (TempSvc.Width * 7 + intSpace * 7)
    Me.Height = (TempSvc.Height * rowcount + intSpace * 7)
    locationPoint.X = 1
    locationPoint.Y = TempSvc.Size.Height * row
    For row = 0 To rowcount - 1
        fp(row) = New FlowLayoutPanel
        fp(row).AutoSize = True
        tempPoint.X = TempSvc.Size.Width : tempPoint.Y = TempSvc.Size.Height
        fp(row).Size = tempPoint
        newLocationPoint.X = locationPoint.X
        newLocationPoint.Y = locationPoint.Y + (TempSvc.Height * row) + spacing * row
        fp(row).Location = newLocationPoint
        Me.Controls.Add(fp(row))
    Next

    For row = 0 To rowcount - 1
        For col = 0 To 6

            'I've tried multiple variations of the following line to no avail
            AddHandler Sv(row, col).LmbClicked, AddressOf myHandler

            Sv(row, col).Name = "SV" + row.ToString + "," + col.ToString()
            Sv(row, col).PutData(EmployeeList(col).ToShiftViewFill)
            fp(row).Controls.Add(Sv(row, col))
        Next
    Next

End Sub


Private Sub myHandler() 'Handles ?
    'Here is where I beiieve I should handle the LmbClicked event
    'and determine which ShiftViewControl fired the event.  Then
    'I can branch to code based on which ShiftViewControl
    'was selected.  Maybe I should use something other than
    'an array?

End Sub

结束班

我不知道如何将“End Class”行放入代码示例中:(

3 个答案:

答案 0 :(得分:0)

每个事件处理程序都应具有相同的基本签名,即类型为sender的{​​{1}}参数和类型为Object的{​​{1}}参数或某些派生类型。 e参数引用引发事件的对象。这就是你总是如何访问引发事件的对象,以及你应该如何确定在你的案例中点击了哪个UC。

答案 1 :(得分:0)

您目前正在处理所有这些点击:lblEmployee.MouseClick, lblJob.MouseClick, lblStartTime.MouseClick, lblEndTime.MouseClick, lblHours.MouseClick, lblRequest.MouseClick, lblNotes.MouseClick, Me.MouseClick, lblSplitShift.MouseClick, lblOverride.MouseClick。这意味着sender As Object中的HandleAllClicks包含对点击的控件的引用。

然后您继续拨打RaiseEvent RmbClicked(Me, e)RaiseEvent LmbClicked(Me, e)。您现在说当前的类(Me)引发了点击。

相反,如果您将其称为RaiseEvent RmbClicked(sender, e)RaiseEvent LmbClicked(sender, e),则可以使用sender变量来确定导致原始点击的控件。

答案 2 :(得分:0)

因此,经过几个小时的反复试验和大量搜索后,我相信我找到了解决方案。这是当前(部分)代码:

        For row = 0 To rowcount - 1
        For col = 0 To 6
            Sv(row, col) = New ShiftViewControl()
            Sv(row, col).Name = "SV" + row.ToString() + "," + col.ToString()

            'EmployeeList() - temporary list just used to generate 
            '   different records in Sv array
            Sv(row, col).PutData(EmployeeList(col).ToShiftViewFill)
            FP(row).Controls.Add(Sv(row, col))

            'This line was correct all along
            AddHandler Sv(row, col).RmbClicked, AddressOf myHandler
        Next
    Next

End Sub


'Yes, the two parameters are needed here.  But NOT needed in the 
' AddHandler line above, as I kept trying to do
Public Sub myHandler(ByVal sender As Object, ByVal e As MouseEventArgs)
    'This works - sender.name returns the   
    '     "SV"+row.tostring+","+col.tostring"    Name as expected
    MsgBox("myHandler" + vbCrLf + _
                        "   sender.name " + DirectCast(sender, ShiftViewControl).Name)

    'sender.name can now be parsed, giving me the array indexes
End Sub

我知道这对专家来说可能很简单。感谢您抽出宝贵时间提供帮助。任何其他批评,评论和建议,请做。除此之外,我相信我已向前迈出了一步。谢谢!