Calendrier sur une semaine (encore) à base tablelayoutpanel


Description

Effectivement, il s'agit d'un affichage de calendrier par semaine... Mon objectif était de travailler sur les TableLayoutPanel et leur propriété de s’auto-dimensionner. L'utilisation du calendrier avec les jours de la semaine associé aux créneaux horaires d'une journée, me semblait un bon point de départ.

Il reste des points à compléter, comme la conservation des saisies textes par horaires.

Les points intéressants sont l'utilisation : des menus contextuels, la création dynamique de TableLayout et de Label, l'édition de texte à partir de la création dynamique d'un TextBox avec une gestion de quelques Events.

J'ai essayé de commenter le code avec, j'espère, peu de fautes "d'hortographes" :-). Tout est dans le Zip, le bout de source, en exemple, illustre la fonction de création des horaires sur 24h et sur 7 jours.

Source / Exemple :

''' -------------------------------------------------------------------------------------
    ''' <summary>
    ''' Construction de la semaine en fonction d'un heure de début et de fin
    ''' </summary>
    ''' <param name="startWork">Début heure d'activité</param>
    ''' <param name="endWork">Fin heure d'activité</param>
    ''' <param name="startDay">heure de début de journée</param>
    ''' <param name="endDay">heure de fin de la journée</param>
    ''' <returns>True, si tout c'est bien passé</returns>
    ''' <remarks>
    ''' La semaine est construite sur les 7 jours de la semaine et sur une durée de journée.
    ''' L'objet TableLayoutPanel est ajouté pour chaque horaire. Cet objet permet une
    ''' extension automatique avec la largeur de la fenêtre et du conteneur (Panel) qui
    ''' assure la scrolling vertical.
    ''' </remarks>
    ''' -------------------------------------------------------------------------------------
    Private Function BuildHourView(Optional ByVal startWork As Integer = 7, Optional ByVal endWork As Integer = 19,
                                   Optional ByVal startDay As Integer = 0, Optional ByVal endDay As Integer = 23) As Boolean
        BuildHourView = False

        ' Control déigné comme visible par défaut au sein de l'objet Panel
        Dim theControl As Control = Nothing

        Try
            ' Vérifications
            If startDay > endDay Then
                ' Inversion des valeurs
                Dim tmpValue As Integer = endDay
                endDay = startDay : startDay = endDay
            ElseIf startDay = endDay Then
                ' Au moins 2 heures
                endDay += 2
            End If

            ' Supprime tous les contrôles existant, 
            ' afin de laisser la place à la nouvelle construction de l'hebdomadaire
            If PanelCalendarWeek.Controls.Count > 0 Then PanelCalendarWeek.Controls.Clear()

            ' Mettre en Invisible accélère le traitement d'ajout des Controls graphiques,
            ' sinon le rafraichissement auto ralenti le traitement global à chaque ajout d'un objet
            PanelCalendarWeek.Visible = False

            ' Position de l'horaire
            Dim theTop As Integer = 0

            ' -------------------------------------------------------------------------------
            ' Création de la liste des Labels Horaires sur 24 heures (ou moins : parametres) 
            ' pour les 7 jours de la semaine 
            For ct As Integer = startDay To endDay
                ' Création du Label (Control) de réception de l'affichage du créneau horaire
                Dim theHour As New System.Windows.Forms.Label

                If theHour IsNot Nothing Then
                    ' Association du Menu Contextuel dédié aux créneaux horaires, pour permettre,
                    ' par exeple, le chnagement de couleur ou de police de caractères.
                    theHour.ContextMenuStrip = MenuContextHour

                    ' -------------------------------------------------------------------------
                    ' Ajout du Label (Control) pour possitionnement et affichage dans le Panel
                    Call PanelCalendarWeek.Controls.Add(theHour)

                    ' Créneau horaire : une sorte d'index utile à l'identification
                    theHour.Tag = ct
                    ' Position
                    theHour.Left = 0 : theHour.Top = theTop
                    ' Dimmension par défaut
                    theHour.Height = 25 : theHour.Width = 50
                    ' Apparence
                    theHour.BorderStyle = BorderStyle.FixedSingle
                    theHour.Font = New Font(theHour.Font.Name, 9, FontStyle.Bold)
                    ' Affichage de l'horaire au centre du Label
                    theHour.Text = Format(ct, "00") & ":00" : theHour.TextAlign = ContentAlignment.MiddleCenter

                    Select Case ct
                        Case Is < startWork
                            ' Une couleur dédiée aux heures creuses
                            theHour.BackColor = CType(MenuHourColorOut.Tag, Color)
                        Case Is > endWork
                            theHour.BackColor = CType(MenuHourColorOut.Tag, Color)
                        Case Else
                            ' Le control par défaut pour un positionnement du Scrollbar du Panel
                            If ct = (endWork - startWork) Then
                                theControl = theHour
                            End If

                            ' La hauteur des Heures d'Activités sont plus doublées, 
                            ' afin de favoriser l'affichage d'information.
                            theHour.Height = theHour.Height * 2 : theTop += 25
                            ' Une couleur dédiée aux heures d'activités
                            theHour.BackColor = CType(MenuHourColorIn.Tag, Color)
                    End Select

                    ' --------------------------------------------------------------
                    ' Création du Tableau horaire pour tous les jours de la semaine
                    Dim hourContent As New TableLayoutPanel

                    If hourContent IsNot Nothing Then
                        ' Ajout du Tableau pour affichage dans le Panel
                        Call PanelCalendarWeek.Controls.Add(hourContent)

                        ' Créneau horaire : une sorte d'index utile à l'identification
                        hourContent.Tag = ct

                        ' Possitionnement et taille par défaut de la "ligne horaire" pour la semaine
                        hourContent.ColumnCount = 7 : hourContent.RowCount = 1
                        hourContent.Top = theHour.Top : hourContent.Left = theHour.Width
                        hourContent.Height = theHour.Height : hourContent.Width = PanelCalendarWeek.Width - theHour.Width

                        ' Couleur associée au créneau horaire
                        hourContent.BackColor = theHour.BackColor
                        ' Pour le redimensionnement automatique
                        hourContent.Anchor = AnchorStyles.Left Or AnchorStyles.Top Or AnchorStyles.Right
                        ' Un contour...
                        hourContent.CellBorderStyle = TableLayoutPanelCellBorderStyle.Single

                        ' Création d'un style pour la hauteur désigné en %
                        Call hourContent.RowStyles.Add(New RowStyle)
                        hourContent.RowStyles(0).SizeType = SizeType.Percent : hourContent.RowStyles(0).Height = 100

                        ' --------------------------------------------------------
                        ' Boucle sur chaque élément du Tableau horaire pour ajout 
                        ' d'un Label d'affichage
                        For ctDay As Integer = 0 To hourContent.ColumnCount - 1
                            ' Création du Label d'affichage lié au Créneau+Jour
                            Dim theDay As New Label

                            If theDay IsNot Nothing Then
                                ' Create dynamical Event Handlers : pour récupérer le Double Click sur les Labels
                                AddHandler theDay.MouseDoubleClick, AddressOf theDay_MouseDoubleClick

                                ' Création d'un style pour chaque colonne, afin de désigné la largeur en %
                                ' Une valeur en % permet une largeur répartie automatiquement.
                                Dim theResult As Integer = hourContent.ColumnStyles.Add(New ColumnStyle)

                                If theResult >= 0 Then
                                    hourContent.ColumnStyles(theResult).SizeType = SizeType.Percent
                                    ' Le pourcentage calculé sur le nombre de cellules du TableLayoutPanel 
                                    hourContent.ColumnStyles(theResult).Width = 14.29 ' (100% / hourContent.ColumnCount) doit donner 14.29%
                                End If

                                ' Ajout du Label au Tableau 
                                Call hourContent.Controls.Add(theDay)

                                ' Mise en forme
                                theDay.Dock = DockStyle.Fill : theDay.TextAlign = ContentAlignment.MiddleCenter : theDay.BackColor = Color.Transparent

                                ' ------------------------------------------------------------------
                                ' Un texte de vérification affiché dans le contenu du Label
                                'theDay.Text = theHour.Text & " - " & Strings.Left(TableWeekDay.GetControlFromPosition(ctDay, 0).Text, 3)
                            End If
                        Next

                        ' Mise à jour de la valeur de position pour le projet ajout de Label Heure
                        theTop += 25
                    End If
                End If
            Next

            Return True

        Catch ex As Exception

        Finally
            ' Affichage du résultat
            PanelCalendarWeek.Visible = True

            ' Fait en sorte que le Control désigné soit visible par le positionnement du Scrollbar
            If theControl IsNot Nothing Then Call PanelCalendarWeek.ScrollControlIntoView(theControl)
        End Try
    End Function

Conclusion :

Ce code est surtout un exercice (de plus) sur l'utilisation d'objet graphique en VB.NET pour réaliser une interface "proche" du calendrier d'un MS Outlook.

Cela pourrait mériter d'en créér un Objet graphique à part entière.

Codes Sources

A voir également

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.