Определить размер формы из другой формы

VB2012: Чтобы выполнить некоторые вычисления в моей основной форме, мне нужно знать размер формы вторичной формы. Размер формы может меняться от пользователя к пользователю в зависимости от ОС и темы. Я понимаю, что размер клиента остается прежним. Однако я думаю, что я делаю что-то не правильно, так как я получаю разные номера в зависимости от того, куда я звоню, чтобы узнать размер формы.

В качестве иллюстрации здесь представлена ​​моя основная форма, в которой при событии load я пытаюсь получить размер формы Alert

Private Sub frmMain_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    'get the default width and height of an Alert form.
    Dim frmW As Integer = frmAlert.Width 'in pixels
    Dim frmH As Integer = frmAlert.Height 'in pixels
    Dim frCsW As Integer = frmAlert.ClientSize.Width 'in pixels
    Dim frmCsH As Integer = frmAlert.ClientSize.Height 'in pixels
    Debug.Print("frmW={0} frmH={1} frCsW={2} frmCsH={3}", frmW, frmH, frCsW, frmCsH)
End Sub

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    'set up a new alert form
    Dim frm As New frmAlert

    'show the alert form
    frm.StartPosition = FormStartPosition.CenterParent
    frm.Show()          'with this option the Alert Forms stay on the screen even if the Main form is minimized.
End Sub

Теперь форма Alert установлена ​​с FormBorderStyle=FixedDialog, ControlBox=False, MaximizeBox=False и MinimizeBox=False, и в форме Alert у меня есть это для события загрузки:

Private Sub frmAlert_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    Debug.Print("me.width={0} me.height={1} cs.width={2} cs.height={3}", Me.Width, Me.Height, Me.ClientSize.Width, Me.ClientSize.Height)
End Sub

и вот вывод отладки

frmW=380 frmH=168 frCsW=374 frmCsH=162
me.width=390 me.height=200 cs.width=374 cs.height=162

Как и ожидалось, размер клиента такой же, но общий размер формы другой. Я пытаюсь обернуть голову вокруг различий в. Высота и. Ширина. Другого кода для изменения свойств формы не существует. Второй оператор отладки соответствует размеру формы в конструкторе IDE. Почему размеры разные? Как бы я правильно запросить, чтобы получить размер формы из другой формы?

2 ответа

Решение

Перед показом формы она будет иметь меньший размер по сравнению с видимой. Это потому, что когда вы показываете форму, Windows будет делать с ней все, что угодно, в зависимости от настроек экрана и темы пользователя, таких как:

  • Измените его, если у пользователя другие настройки DPI.
  • Примените границы к нему на основе выбранной пользователем темы окна.
  • (так далее.)

Лучше всего сначала показать форму, а затем узнать ее размер.

Если вы не хотите, чтобы форма была видна сразу, вы можете установить ее Opacity свойство 0, чтобы сделать его невидимым, затем измените его обратно на 1.0, как только вам нужно будет показать форму пользователю.

Итак, основываясь на предложении @Visual Vincent, я создал конструктор при создании новой формы. Это идет в frmAlert.Designer.vb

Partial Class frmAlert
    Private mIsProcessFormCode As Boolean = True

    Public Sub New()
        ' This call is required by the designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.
        Me.mIsProcessFormCode = True
    End Sub

    Public Sub New(ByVal IsProcessFormCode As Boolean)
        ' This call is required by the designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.
        Me.mIsProcessFormCode = IsProcessFormCode
    End Sub
End Class

Затем на frmMain я добавляю этот код:

Private Sub frmMain_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    Debug.Print("routine={0}", System.Reflection.MethodBase.GetCurrentMethod.Name)
    Dim frm As New frmAlert(False) 'create an instance of the form without any of the Form processes
    frm.Opacity = 0 'makes the form totally transparent
    frm.Visible = False
    frm.Show()
    Dim frmWidth As Integer = frm.Width
    Dim frHeight As Integer = frm.Height
    Dim frCsWidth As Integer = frm.ClientSize.Width
    Dim frCsHeight As Integer = frm.ClientSize.Height
    frm.Close()
    frm.Dispose()
    Debug.Print("frmWidth={0} frHeight={1} frCsWidth={2} frCsHeight={3}", frmWidth, frHeight, frCsWidth, frCsHeight)
End Sub

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Debug.Print("routine={0}", System.Reflection.MethodBase.GetCurrentMethod.Name)

    'set up the alert form normally
    Dim frm As New frmAlert

    'show the alert form
    frm.StartPosition = FormStartPosition.CenterParent
    frm.Show()          'with this option the Alert Forms stay on the screen even if the Main form is minimized.
End Sub

и в frmAlert я добавляю этот код:

Private Sub frmAlert_FormClosed(sender As Object, e As FormClosedEventArgs) Handles Me.FormClosed
    Try
        'process the form code ONLY if required
        Debug.Print("routine={0} mIsProcessFormCode={1}", System.Reflection.MethodBase.GetCurrentMethod.Name, mIsProcessFormCode)
        If mIsProcessFormCode Then
            'do Closed stuff
        End If
    Catch ex As Exception
        Debug.Print(ex.ToString)
    End Try
End Sub

Private Sub frmAlert_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
    Try
        'process the form code ONLY if required
        Debug.Print("routine={0} mIsProcessFormCode={1}", System.Reflection.MethodBase.GetCurrentMethod.Name, mIsProcessFormCode)
        If mIsProcessFormCode Then
            'do Closing stuff
        End If
    Catch ex As Exception
        Debug.Print(ex.ToString)
    End Try
End Sub

Private Sub frmAlert_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    Try
        'process the form code ONLY if required
        Debug.Print("routine={0} mIsProcessFormCode={1}", System.Reflection.MethodBase.GetCurrentMethod.Name, mIsProcessFormCode)
        Debug.Print("me.width={0} me.height={1} cs.width={2} cs.height={3}", Me.Width, Me.Height, Me.ClientSize.Width, Me.ClientSize.Height)
        If mIsProcessFormCode Then
            'process text file
        End If
    Catch ex As Exception
        Debug.Print(ex.ToString)
    End Try
End Sub

и отладочный вывод:

routine=frmMain_Load
routine=frmAlert_Load mIsProcessFormCode=False
me.width=390 me.height=200 cs.width=374 cs.height=162
routine=frmAlert_FormClosing mIsProcessFormCode=False
routine=frmAlert_FormClosed mIsProcessFormCode=False
frmWidth=390 frHeight=200 frCsWidth=374 frCsHeight=162
routine=Button1_Click
routine=frmAlert_Load mIsProcessFormCode=True
me.width=390 me.height=200 cs.width=374 cs.height=162

Я верю, что это то, что я хочу. Все размеры frmAlert совпадают с тем, что есть в конструкторе IDE. Если вы можете подумать о каких-либо модификациях, пожалуйста, дайте мне знать. Большое спасибо.

Другие вопросы по тегам