Incastonare una form in un'altra non MDI

E' stato chiesto nel forum .Net come incastonare una form secondaria nella ClientArea della form chiamante senza essere costretti in un sistema di form MDI Parent o Child.

Ci ho studiato un po' su e, poiché la soluzione richiede un certo impianto, posto qui la soluzione, anziché in un messaggio di risposta.

Poiché è una eventualità da considerare anche per altre form, nella nostra applicazione, è d'uopo implementare una classe statica, con un metodo da richiamare negli eventi Move e Resize delle form stesse.

Non solo. L'idea era di delegare anche la gestione di questi eventi a un metodo della classe statica, ma l'esecuzione provoca uno sfarfallìo sgradevole. Di conseguenza ho ripiegato su una gestione separata per ciascuna form interessata.

Questa è la classe statica (chiaramente, si può spostare il suo unico metodo in una qualsiasi altra classe statica con analoghe funzionalità di gestione di interfaccia utente).

Public Class ResizeFormHelper

  Public Shared Sub ResizeFormInClientArea(ByVal ownerForm As Form, ByVal clientForm As Form)
    If clientForm IsNot Nothing Then
      clientForm.Size = ownerForm.ClientSize
      clientForm.Visible = False
      clientForm.Show(ownerForm)
      clientForm.Top = ownerForm.Top + SI.CaptionHeight + SI.HorizontalResizeBorderThickness
      clientForm.Left = ownerForm.Left + SI.VerticalResizeBorderThickness
    End If
  End Sub

End Class

In questo codice ci si riferisce a SI, che non è altro che l'alias di un namespace importato nello stesso modulo:

Imports SI = System.Windows.Forms.SystemInformation

 Infatti, le informazioni  fornite da questo namespace sono essenziali per ricalcolare la posizione della form secondaria, le cui dimensioni, invece, sono semplicemente quelle della ClientArea della form proprietaria.

Per comodità, ho supposto di voler incastonare l'una nell'altra due (o più) istanze della stessa form, nella quale ho disegnato solo un pulsante. Questo il codice essenziale:

Public Class Form1

  Dim f2 As Form1

  Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
                            Handles Button1.Click
    f2 = New Form1
    f2.Owner = Me
    f2.Text = "Form" & (Integer.Parse(Me.Text.Substring(4)) + 1).ToString
    f2.Width += 1

  End Sub

  Private Sub Form1_Move(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Move
    ResizeHandler()
  End Sub

  Private Sub Form1_Resize(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Resize
    ResizeHandler()
  End Sub

  Private Sub ResizeHandler()
    ResizeFormHelper.ResizeFormInClientArea(Me, f2)
    If Me.Owner IsNot Nothing Then
      ResizeFormHelper.ResizeFormInClientArea(Owner, Me)
    End If
  End Sub

End Class

Nella Button1_Click, viene istanziata una nuova form, se ne imposta il proprietario, il titolo, la larghezza (quest'ultima proprietà al solo scopo di scatenare il suo evento Resize). La soluzione richiede che ogni form facente parte di questo sistema sia Owner o Owned o entrambe le cose, e che gli eventi Move e  Resize richiamino lo stesso metodo, ResizeHandler, il quale usa il metodo ResizeFormInClientArea della classe statica ResizeFormHelper.

Print | posted @ lunedì 27 aprile 2009 17:03

Comments have been closed on this topic.