Redimensionnement automatique du contenu d'un form en vb.net

Soyez le premier à donner votre avis sur cette source.

Vue 24 138 fois - Téléchargée 2 810 fois

Description

Je me suis inspiré d'un code déposé en CSharp.NET par "bestmomo" (http://www.csharpfr.com/code.aspx?ID=33792), que j'ai transcrit en VB.NET, un peu amélioré, et surtout dans lequel j'ai corrigé un bug qui m'a fait tourner en bourrique pendant un moment.

Pour ceux qui iront fouiner dans le code
========================================

La version de "bestmomo" est basée sur la mémorisation (dans un tableau unidimensionnel de structures) des tailles, positions et fonts de la liste des controles contenus dans la Form, ainsi que de leurs conteneurs respectifs. Cela se fait par balayage, grâce à une fonction récursive, de l'arborescence des controles.

Ensuite, lorsque le Resize est demandé, l'arborescence de controles est à nouveau balayée, et l'ancienne taille stockée dans le tableau de structures est modifiée (augmentée ou diminuée) suivant la nouvelle taille de la Form.

Or je me suis aperçu, sur un exemple de Form contenant près de 200 controles, que l'arborescence des controles n'est pas forcément balayée dans le même ordre à deux instants très proches l'un de l'autre. D'où un décalage qui fait que les contrôles sont redimensionnés n'importe comment.

D'autre part, il y a un problème si la Form contient un DataGrid, car un Datagrid peut contenir lui-même des contrôles (TextBox, CheckBox, ou autre). Ma classe 'Resize' s'arrête au niveau de la Datagrid elle-même, sans tenir compte des éventuels contrôles qu'elle contiendrait.

La méthode 'DoResize' possède un argument vrai/faux qui permet d'adapter la taille de la police de chaque contrôle (sauf les Datagrids), et un autre argument qui permet d'affecter un coefficient multiplicateur à la police contenue dans les Datagrids, mais cette dernière fonctionnalité n'est pas au point. Mettre ce dernier à 0 pour l'ignorer.

J'ai fait des tests sur une Form contenant environ 200 contrôles (dont une dizaine de Datagrids), des panels, des groupBox, et conteneurs divers, répartis sur 5 onglets, pas de problèmes. Par contre, avec une telle quantité de controles, ca pédale un peu.

Sur un exemple plus simple tel que celui contenu dans le ZIP, ca marche nickel.

Voilà, I hope this will help you !

Codes Sources

A voir également

Ajouter un commentaire

Commentaires

Messages postés
115
Date d'inscription
jeudi 11 octobre 2001
Statut
Membre
Dernière intervention
15 octobre 2012

Bonjour,
Intéressant mais je me suis permis juste pour le plaisir de le modifier légèrement
Maintenant juste la création du composant est nécessaire sur la form plus besoin de spécifier d'autres choses
donc dans la form juste :
Private formSizer As ControlsResize = New ControlsResize(True, Me, True, ValueForDatagrid) doit être présent.
Possibilité de passer chaque valeurs, d'activer ou non le resize des composants

Imports System.Windows.Forms
Imports System.Collections
Imports System.Drawing

Public Class ControlsResize
    Inherits System.ComponentModel.Component

#Region "Variables locales"
    ' Variable nécessaire au concepteur.
    Private components As System.ComponentModel.Container = Nothing

    Public WithEvents Cont As Control
    Private FormParent As Form
    Public LastFormState As Windows.Forms.FormWindowState
    Public Facteur_redim_datagrids As Integer = 0
    Public AjustementPolice As Boolean
    Public ResizeActived As Boolean = False

    ' Structure pour mémoriser les dimensions
    Private Structure ControlProperties
        Public Top, Left, Height, Width, ContHeight, ContWidth As Integer
        Public FntSize As Single
        Public ctl As control
    End Structure

    ' Variable de mémorisation des dimensions de départ
    Private MemoSize As ArrayList = New ArrayList
#End Region

#Region " Constructeurs "
    Public Sub New(ByVal container As System.ComponentModel.IContainer)
        ' Requis pour la prise en charge du Concepteur de composition de classes Windows.Forms
        container.Add(Me)
        components = New System.ComponentModel.Container
    End Sub

    Public Sub New()
        ' Requis pour la prise en charge du Concepteur de composition de classes Windows.Forms
        components = New System.ComponentModel.Container
    End Sub

    Public Sub New(ByVal ResizeActived As Boolean, ByVal cc As Control, ByVal Ajuste_Polices As Boolean, ByVal facteur_redim_datagrids As Integer)
        MyBase.New()
        InitResize(ResizeActived, cc, Ajuste_Polices, facteur_redim_datagrids)
    End Sub

#End Region

#Region " Initialisation "
    ' paramètre "Ajuste_Polices" : Ajustement optionnel des polices
    ' mettre False pour que les polices gardent leur taille initiale
    Public Sub InitResize(ByVal ResizeActived As Boolean, ByVal cc As Control, ByVal Ajuste_Polices As Boolean, ByVal facteur_redim_datagrids As Integer)
        Me.ResizeActived = ResizeActived
        Me.Cont = cc
        Me.AjustementPolice = Ajuste_Polices
        Me.Facteur_redim_datagrids = facteur_redim_datagrids
        Me.MemoSize.Clear()
        Me.Init(Me.Cont)
    End Sub

    ' Sauvegarde valeurs de départ
    Private Sub Init(ByVal cc As Control)
        Dim ctl As Control
        Dim tCtlProp As ControlProperties = New ControlProperties

        For Each ctl In cc.Controls
            tCtlProp.Height = ctl.Height
            tCtlProp.Width = ctl.Width
            tCtlProp.Top = ctl.Top
            tCtlProp.Left = ctl.Left
            tCtlProp.FntSize = ctl.Font.Size
            tCtlProp.ContHeight = cc.Height
            tCtlProp.ContWidth = cc.Width
            tCtlProp.ctl = ctl
            Me.MemoSize.Add(tCtlProp)
            ' Appel récursif pour les contrôles enfants sauf pour les DataGrids
            If ctl.Controls.Count > 0 AndAlso Not TypeOf ctl Is DataGrid Then
                Me.Init(ctl)
            End If
        Next
    End Sub
#End Region

#Region "Méthodes publiques"

    ' Redimensionnement des contrôles
    Public Sub DoResize()
        If Me.ResizeActived Then Me.Resize()
    End Sub

    Private Sub Resize()
        Dim tCtlProp As ControlProperties
        Dim dProportionateHeight, dProportionateWidth As Single
        Dim i As Integer

        Try
            If Not Me.ResizeActived Then Exit Sub

            ' Redimensionnement des contrôles
            For i = 0 To MemoSize.Count - 1
                ' Récupération des valeurs initiales
                tCtlProp = MemoSize(i)
                ' Calcul des proportions largeur et hauteur
                dProportionateHeight = tCtlProp.ctl.Parent.Height / tCtlProp.ContHeight
                dProportionateWidth = tCtlProp.ctl.Parent.Width / tCtlProp.ContWidth

                ' Calcul des nouvelles dimensions
                tCtlProp.ctl.SetBounds(CType((tCtlProp.Left * dProportionateWidth), Integer), _
                            CType((tCtlProp.Top * dProportionateHeight), Integer), _
                            CType((tCtlProp.Width * dProportionateWidth), Integer), _
                            CType((tCtlProp.Height * dProportionateHeight), Integer))

                If Me.AjustementPolice Then  ' Ajustement des polices optionnelle sauf pour DataGrid
                    If Not TypeOf tCtlProp.ctl Is DataGrid Then
                        tCtlProp.ctl.Font = New Font(tCtlProp.ctl.Font.FontFamily, _
                            tCtlProp.FntSize * dProportionateHeight, _
                            tCtlProp.ctl.Font.Style)
                    End If
                End If
            Next

        Catch ex As Exception
            'on lève l'exception qui vient d'être interceptée
            ' pour la faire remonter au programme appelant
            Throw ex
        End Try
    End Sub

#End Region

    Private Sub Cont_HandleCreated(ByVal sender As Object, ByVal e As System.EventArgs) Handles Cont.HandleCreated
        FormParent = Cont.FindForm 'Récupère la form conteneur
        Me.InitResize(ResizeActived, Cont, AjustementPolice, Facteur_redim_datagrids)
    End Sub

    Private Sub Cont_Resize(ByVal sender As Object, ByVal e As System.EventArgs) Handles Cont.Resize
        If Not FormParent Is Nothing Then
            If FormParent.WindowState <> Windows.Forms.FormWindowState.Minimized And Cont.Created And Cont.IsHandleCreated And LastFormState <> FormWindowState.Minimized Then
                Me.DoResize()
            End If
        End If

        If Me.LastFormState = FormWindowState.Minimized Then
            Me.InitResize(ResizeActived, Cont, AjustementPolice, Facteur_redim_datagrids)
        End If

        If Not FormParent Is Nothing Then LastFormState = FormParent.WindowState
    End Sub
End Class

Messages postés
106
Date d'inscription
lundi 20 septembre 2004
Statut
Membre
Dernière intervention
23 janvier 2010

Si si ça marche très bien après import sous Visual Studio 2008

Par contre il ne faut absolument pas réduire la fenêtre dans la barre des taches puis la réafficher.

En tout cas très bon code, je vais essayer de voir ou est le problème.
bon alors

j'ai rajouté une propriété à ta classe :
Public lastFormState As Windows.Forms.FormWindowState

et ensuite dans le resize :

If Me.WindowState <> Windows.Forms.FormWindowState.Minimized And Me.Created And Me.IsHandleCreated And formSizer.lastFormState <> FormWindowState.Minimized Then
' mettre False dans DoResize pour que les polices gardent leur taille initiale
formSizer.DoResize(Me, True, facteur_redim_datagrids)
End If
If formSizer.lastFormState = FormWindowState.Minimized Then
formSizer.InitResize(Me)
End If
formSizer.lastFormState = Me.WindowState

et j'ai supprimé le code dans l'évènement size_changed.

Et je n'ai plus ce problème.

Bon coding à tous
Messages postés
257
Date d'inscription
jeudi 11 septembre 2008
Statut
Membre
Dernière intervention
22 décembre 2012
1
Bien dommage que cette source ne fonctionne pas en VB NET 2008. snif
Messages postés
113
Date d'inscription
vendredi 5 mars 2004
Statut
Membre
Dernière intervention
11 février 2008

Problème: quand je réduis la fenêtre, et que je la rends visible de nouveau. J'ai cette fenêtre mais avec juste le coin haut gauche. On a l'impression d'un zoom sur un carré en haut à gauche de la fentre... Est-ce déjà arrivé à quelqu'un ?
Messages postés
30
Date d'inscription
vendredi 23 avril 2004
Statut
Membre
Dernière intervention
1 juin 2011

Salut à tous.

en .net, il suffit d'organiser sa form avec des tableaux et la propriété dock des objets en fill, les redimensionnement se font tout seul.

Bonne continuation
Afficher les 15 commentaires

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.