DarkTerritory
DarkTerritory

Reputation: 125

Capture focus event on form click

I have three forms in a VB.Net 2015 project that all need to move together as one. It's possible for the user to click and drag any of the three, and the other two should move with them. I have the movement down, and have code in each form to direct the others. but I'm struggling with how to determine which form should be the master (as the other two should not implement their Move() code if they are not).

I had the idea to establish a global String variable that would be loaded with the form name when a form is clicked, and cleared when it is released. Each form checks to see it it has the priority on the move() event and if not it ignores it.

But I can't seem to figure out how to identify the form with focus.

I've tried the MouseDown and MouseUp events, the Click event, and a few others, but nothing fires. I have learned that forms don't react to these events if they have any visible or enabled controls on them. But there has to be something I can use (other than the Move() event) to help with this?

Private Sub frm1_Move(sender As Object, e As EventArgs) Handles Me.Move

    ' Causes the Product List and Event Monitor windows to move with the Induct Status form when it is moved  CJB 6/12/2019
    ' Global variable for new form movement -- gsTriFormFocus (String) -- Place Form Name in field when Form MouseDown event fires, clear with "" when MouseUp event fired  ' CJB 6/24/2019

    If gsTriFormFocus <> "frm1" Then
        Exit Sub
    Else

        Dim frm As New Form

        frm.Tag = "frm2"
        If gcolProjectForm.Count > 0 Then
            For i As Integer = 1 To gcolProjectForm.Count
                If gcolProjectForm(i).tag.ToString.ToUpper = (frm.Tag.ToUpper) Then
                    gcolProjectForm(i).Left = Me.Left
                    gcolProjectForm(i).Top = Me.Top + Me.Height + 10
                    Exit For
                End If
            Next
        End If

        frm.Tag = "frm3"
        If gcolProjectForm.Count > 0 Then
            For i As Integer = 1 To gcolProjectForm.Count
                If gcolProjectForm(i).tag.ToString.ToUpper = (frm.Tag.ToUpper) Then
                    gcolProjectForm(i).Left = Me.Left + Me.Width + 10
                    gcolProjectForm(i).Top = Me.Top
                    Exit For
                End If
            Next
        End If
    End If

End Sub

Upvotes: 0

Views: 300

Answers (2)

Idle_Mind
Idle_Mind

Reputation: 39132

Looks to me like you want frm2 below frm1, and frm3 to the right of frm1.

Here's the code for frm1:

Public Class frm1

    Public Shared Ignore As Boolean = False

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Dim f2 As New frm2
        f2.Show()

        Dim f3 As New frm3
        f3.Show()

        UpdateForms(Me)
    End Sub

    Private Sub frm1_LocationChanged(sender As Object, e As EventArgs) Handles Me.LocationChanged
        UpdateForms(Me)
    End Sub

    Private Sub frm1_SizeChanged(sender As Object, e As EventArgs) Handles Me.SizeChanged
        UpdateForms(Me)
    End Sub

    Public Shared Sub UpdateForms(ByVal sourceForm As Form)
        If Not Ignore Then
            Ignore = True

            Dim f1 As frm1 = Application.OpenForms.OfType(Of frm1).FirstOrDefault
            Dim f2 As frm2 = Application.OpenForms.OfType(Of frm2).FirstOrDefault
            Dim f3 As frm3 = Application.OpenForms.OfType(Of frm3).FirstOrDefault

            If sourceForm Is f1 Then
                If Not IsNothing(f2) Then
                    f2.Location = New Point(f1.Bounds.Left, f1.Bounds.Bottom + 10) ' below frm1
                End If
                If Not IsNothing(f3) Then
                    f3.Location = New Point(f1.Bounds.Right + 10, f1.Bounds.Top) ' to the right of frm1
                End If
            ElseIf sourceForm Is f2 Then
                If Not IsNothing(f1) Then
                    f1.Location = New Point(f2.Bounds.Left, f2.Bounds.Top - f1.Bounds.Height - 10) ' above frm2
                End If
                If Not IsNothing(f3) AndAlso Not IsNothing(f1) Then
                    f3.Location = New Point(f1.Bounds.Right + 10, f1.Bounds.Top) ' to the right of frm1
                End If
            ElseIf sourceForm Is f3 Then
                If Not IsNothing(f1) Then
                    f1.Location = New Point(f3.Bounds.Left - f1.Bounds.Width - 10, f3.Bounds.Top) ' to the left of frm3
                End If
                If Not IsNothing(f2) AndAlso Not IsNothing(f1) Then
                    f2.Location = New Point(f1.Bounds.Left, f1.Bounds.Bottom + 10) ' below frm1
                End If
            End If

            Ignore = False
        End If
    End Sub

End Class

Then frm2 and frm3 are much simpler:

Public Class frm2

    Private Sub frm2_LocationChanged(sender As Object, e As EventArgs) Handles Me.LocationChanged
        frm1.UpdateForms(Me)
    End Sub

End Class

Public Class frm3

    Private Sub frm3_LocationChanged(sender As Object, e As EventArgs) Handles Me.LocationChanged
        frm1.UpdateForms(Me)
    End Sub

End Class

Upvotes: 1

LarsTech
LarsTech

Reputation: 81610

Use the LocationChanged event handler to handle this:

Private frm2 As New Form2
Private frm3 As New Form3

Public Sub New()
  InitializeComponent()
  AddHandler frm2.LocationChanged,
    Sub()
      Me.Location = New Point(frm2.Left - Me.Width, frm2.Top)
    End Sub
  frm2.Show()

  AddHandler frm3.LocationChanged,
    Sub()
      Me.Location = New Point(frm3.Left - Me.Width, frm3.Top - frm2.Height)
    End Sub
  frm3.Show()
End Sub

Protected Overrides Sub OnLocationChanged(e As EventArgs)
  MyBase.OnLocationChanged(e)
  frm2.Location = New Point(Me.Left + Me.Width, Me.Top)
  frm3.Location = New Point(frm2.Left, frm2.Top + frm2.Height)
End Sub

Upvotes: 1

Related Questions