none
Utilizzo di TableLayoutPanel RRS feed

  • Domanda

  • Buon giorno, stò tentando di utilizzare il controllo TableLayoutPanel per appoggiarci, in modo dinamico, dei bottoni ma non riesco a proporzionare correttamente le dimensioni delle colonne. Ho guardato gli esempi di MSDN e quelli che ho trovato in rete ma, evidentemente, mi sfugge qualcosa. Nella figura riportata si può vedere come si ridistribuisce lo spazio del controllo per contenere 5 bottoni con ripartizione %le.

    Il codice che ho scritto, per quello che ho capito, è riportato a seguire

        Private Sub addButtons(ByVal tablelayoutpanel1 As TableLayoutPanel, ByVal bottoni As List(Of String), ByVal Scelto As Short)
            tablelayoutpanel1.ColumnCount = Bottoni.Count
            tablelayoutpanel1.Height = 40
            tablelayoutpanel1.Width = Me.Width - 20
            tablelayoutpanel1.AutoSize = False
            tablelayoutpanel1.BackColor = Color.Azure
            For i As Integer = 0 To tablelayoutpanel1.ColumnCount - 1
                Dim Btn As New Button
                With Btn
                    .Height = 210
                    .Name = "Button" & i + 1
                    .Font = New System.Drawing.Font("Microsoft Sans Serif", 10.0!, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
                    .Text = bottoni(i)
                    .Dock = DockStyle.Fill
                End With
                tablelayoutpanel1.Controls.Add(Btn)
            Next
            For Each myControl As Control In tablelayoutpanel1.Controls
                Dim styles As TableLayoutColumnStyleCollection = Me.TableLayoutPanel1.ColumnStyles
                For Each style As ColumnStyle In styles
                    Debug.Print(myControl.Text & " **** " & style.SizeType.ToString)
                    If style.SizeType <> SizeType.Percent Then
                        style.SizeType = SizeType.Percent
                    End If
                    style.Width = 100 / tablelayoutpanel1.ColumnCount
                    Debug.Print(myControl.Text & "    " & style.Width)
                    AddHandler myControl.MouseEnter, AddressOf Bottone_MouseEnter
                    AddHandler myControl.MouseLeave, AddressOf Bottone_Mouseleave
                    AddHandler myControl.MouseClick, AddressOf Bottone_MouseClick
                    Exit For
                Next style
            Next myControl
            'Next
        End Sub
    


    Per quanti sforzi faccia non riesco a capire la ripartizione che viene fuori.

    Cortesemente riuscite a darmi una mano?

    grazie matylda

    mercoledì 30 ottobre 2013 00:26

Risposte

  • Non avevi aggiornato i ColumnStyles che rimanevano quelli di default (cioè 2 o quelli che sono nel tuo caso).

    Aggiungi le righe di seguito indicate dal commento AGGIUNGERE

    L'ultima colonna, in alcuni casi, può risultare leggermente più lunga delle altre. Dovrebbe essere un problema di arrotondamenti.

    Private Sub addButtons(ByVal tablelayoutpanel1 As TableLayoutPanel, ByVal bottoni As List(Of String), ByVal Scelto As Short) tablelayoutpanel1.ColumnStyles.Clear() ' <-- AGGIUNGERE Dim cs As ColumnStyle ' <-- AGGIUNGERE For i As Integer = 0 To tablelayoutpanel1.ColumnCount - 1 Dim Btn As New Button With Btn .Name = "Button" & i + 1 .Font = New System.Drawing.Font("Microsoft Sans Serif", 9.0!, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, CType(0, Byte)) .Text = bottoni(i) .Dock = DockStyle.Fill End With tablelayoutpanel1.Controls.Add(Btn) AddHandler Btn.MouseEnter, AddressOf Bottone_MouseEnter AddHandler Btn.MouseLeave, AddressOf Bottone_Mouseleave AddHandler Btn.MouseClick, AddressOf Bottone_MouseClick cs = New ColumnStyle ' <-- AGGIUNGERE tablelayoutpanel1.ColumnStyles.Add(cs) ' <-- AGGIUNGERE Next

    ...

    ...


    • Contrassegnato come risposta Matylda giovedì 31 ottobre 2013 08:51
    giovedì 31 ottobre 2013 07:08

Tutte le risposte

  •         For Each myControl As Control In tablelayoutpanel1.Controls
                Dim styles As TableLayoutColumnStyleCollection = Me.TableLayoutPanel1.ColumnStyles
                For Each style As ColumnStyle In styles
                    Debug.Print(myControl.Text & " **** " & style.SizeType.ToString)
                    If style.SizeType <> SizeType.Percent Then
                        style.SizeType = SizeType.Percent
                    End If
                    style.Width = 100 / tablelayoutpanel1.ColumnCount
                    Debug.Print(myControl.Text & "    " & style.Width)
                    AddHandler myControl.MouseEnter, AddressOf Bottone_MouseEnter
                    AddHandler myControl.MouseLeave, AddressOf Bottone_Mouseleave
                    AddHandler myControl.MouseClick, AddressOf Bottone_MouseClick
                    Exit For
                Next style
            Next myControl
    

    I due cicli For fanno cose differenti e vanno separati. L'Exit For non serve.

    mercoledì 30 ottobre 2013 08:40
  • Nel For Each myControl... vanno gli AddHandler.

    Nel For Each style... il SizeType e la Width.

    mercoledì 30 ottobre 2013 08:50
  • Gli AddHandler potrebbero andare anche nel For i iniziale, applicati a Btn.
    mercoledì 30 ottobre 2013 08:53
  • Grazie per l'attenzione ma il risultato non cambia. La versione originale prevedeva i cicli separati, poi per cercare di capire ho provato anche a unirli. Ti ri invio sia il codice, modificato secondo le tue osservazioni, che lo screenshot risultante.

    grazie, matylda

        Private Sub addButtons(ByVal tablelayoutpanel1 As TableLayoutPanel, ByVal bottoni As List(Of String), ByVal Scelto As Short)
    
            With tablelayoutpanel1
                .ColumnCount = bottoni.Count
                .Height = 40
                .Width = Me.Width - 20
                .AutoSize = False
                .BackColor = Color.Azure
            End With
    
            For i As Integer = 0 To tablelayoutpanel1.ColumnCount - 1
                Dim Btn As New Button
                With Btn
                    .Height = 210
                    .Name = "Button" & i + 1
                    .Font = New System.Drawing.Font("Microsoft Sans Serif", 10.0!, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
                    .Text = bottoni(i)
                    .Dock = DockStyle.Fill
                End With
                tablelayoutpanel1.Controls.Add(Btn)
                AddHandler Btn.MouseEnter, AddressOf Bottone_MouseEnter
                AddHandler Btn.MouseLeave, AddressOf Bottone_Mouseleave
                AddHandler Btn.MouseClick, AddressOf Bottone_MouseClick
            Next
    
            For Each myControl As Control In tablelayoutpanel1.Controls
                Dim styles As TableLayoutColumnStyleCollection = Me.TableLayoutPanel1.ColumnStyles
                For Each style As ColumnStyle In styles
                    Debug.Print(myControl.Text & " **** " & style.SizeType.ToString)
                    If style.SizeType <> SizeType.Percent Then
                        style.SizeType = SizeType.Percent
                    End If
                    style.Width = 100 / tablelayoutpanel1.ColumnCount
                    Debug.Print(myControl.Text & "    " & style.Width)
                    Exit For
                Next style
            Next myControl
        End Sub
    

    mercoledì 30 ottobre 2013 10:08
  • Grazie per l'attenzione ma il risultato non cambia. La versione originale prevedeva i cicli separati, poi per cercare di capire ho provato anche a unirli. Ti ri invio sia il codice, modificato secondo le tue osservazioni, che lo screenshot risultante.

    grazie, matylda

    For Each myControl As Control In tablelayoutpanel1.Controls '
    '^^^^^^^^^^^^^^^^^
    ' RIMUOVERE

    Dim styles As TableLayoutColumnStyleCollection = Me.TableLayoutPanel1.ColumnStyles For Each style As ColumnStyle In styles

    ...

    Exit For ' <--- RIMUOVERE Next style Next myControl ' <--- RIMUOVERE


    Hai ancora due cicli uno dentro l'altro.

    In questo blocco, "For Each myControl..." non ti serve più e, se non togli l'exit for, il ciclo più interno lo esegui una sola volta e non imposti l'ampiezza delle altre colonne.





    • Modificato BlueLed mercoledì 30 ottobre 2013 13:19
    mercoledì 30 ottobre 2013 13:17
  • In sostanza, nell'ultima parte, dovrebbe bastare questo:

                Dim styles As TableLayoutColumnStyleCollection = Me.TableLayoutPanel1.ColumnStyles
                For Each style As ColumnStyle In styles
                    
                    If style.SizeType <> SizeType.Percent Then
                        style.SizeType = SizeType.Percent
                    End If
                    style.Width = 100 / tablelayoutpanel1.ColumnCount
                    
                Next style



    • Modificato BlueLed mercoledì 30 ottobre 2013 13:22
    mercoledì 30 ottobre 2013 13:21
  • In sostanza, nell'ultima parte, dovrebbe bastare questo:

                Dim styles As TableLayoutColumnStyleCollection = Me.TableLayoutPanel1.ColumnStyles
                For Each style As ColumnStyle In styles
                    
                    If style.SizeType <> SizeType.Percent Then
                        style.SizeType = SizeType.Percent
                    End If
                    style.Width = 100 / tablelayoutpanel1.ColumnCount
                    
                Next style



    Ciao, le ho provate tutte seguendo anche i tuoi consigli ma questo screen shot riassume tutti i risultati,

    dai quali puoi vedere che le ripartizioni degli spazi non sono quelle aspettate. Comunque ti allego anche tutto il codice affinchè possa essere controllato.

    grazie matylda

    Public Class Form1
    
        Protected Overrides Sub Finalize()
            MyBase.Finalize()
        End Sub
    
        Public Sub New()
    
            ' Chiamata richiesta dalla finestra di progettazione.
            InitializeComponent()
    
            ' Aggiungere le eventuali istruzioni di inizializzazione dopo la chiamata a InitializeComponent().
            TableLayoutPanel1.Width = Me.Width '- 10
        End Sub
        Public Scelto As Short = -1
        Public Bottoni As New List(Of String)
    
        Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
            TableLayoutPanel1.Controls.Clear()
            Dim styles As TableLayoutColumnStyleCollection = Me.TableLayoutPanel1.ColumnStyles
            For Each style As ColumnStyle In styles
                Debug.Print("********** style.SizeType = " & style.SizeType.ToString & " style.Width = " & style.Width)
            Next style
            Bottoni.Clear()
            TableLayoutPanel1.ColumnCount = CType(TextBox1.Text, Integer)
    
            For i As Integer = 0 To CType(TextBox1.Text, Integer) - 1
                Bottoni.Add("Bottone " & i + 1)
            Next
    
            With TableLayoutPanel1
                .ColumnCount = Bottoni.Count
                .Height = 40
                .MaximumSize = New System.Drawing.Size(Me.Width - 18, 40)
                .AutoSize = False
                .BackColor = Color.Azure
            End With
    
            addButtons(TableLayoutPanel1, Bottoni, Scelto)
    
            Debug.Print("*** tablelayoutpanel1.Width = " & TableLayoutPanel1.Width & " ***")
            'Dim styles As TableLayoutColumnStyleCollection = Me.TableLayoutPanel1.ColumnStyles
            For Each style As ColumnStyle In styles
                Debug.Print("********** style.SizeType = " & style.SizeType.ToString & " style.Width = " & style.Width)
            Next style
        End Sub
        Private Sub addButtons(ByVal tablelayoutpanel1 As TableLayoutPanel, ByVal bottoni As List(Of String), ByVal Scelto As Short)
    
            For i As Integer = 0 To tablelayoutpanel1.ColumnCount - 1
                Dim Btn As New Button
                With Btn
                    .Name = "Button" & i + 1
                    .Font = New System.Drawing.Font("Microsoft Sans Serif", 9.0!, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
                    .Text = bottoni(i)
                    .Dock = DockStyle.Fill
                End With
                tablelayoutpanel1.Controls.Add(Btn)
                AddHandler Btn.MouseEnter, AddressOf Bottone_MouseEnter
                AddHandler Btn.MouseLeave, AddressOf Bottone_Mouseleave
                AddHandler Btn.MouseClick, AddressOf Bottone_MouseClick
            Next
    
            Dim styles As TableLayoutColumnStyleCollection = Me.TableLayoutPanel1.ColumnStyles
            For Each style As ColumnStyle In styles
                'Debug.Print("++++ style.SizeType = " & style.SizeType.ToString & " style.Width = " & style.Width)
                style.SizeType = SizeType.Percent
                style.Width = 100 / tablelayoutpanel1.ColumnCount
                Debug.Print("---- style.SizeType = " & style.SizeType.ToString & " style.Width = " & style.Width)
            Next style
        End Sub
    
        Private Sub Bottone_MouseEnter(sender As System.Object, e As System.EventArgs)
            sender.forecolor = Color.Red
        End Sub
        Private Sub Bottone_Mouseleave(sender As System.Object, e As System.EventArgs)
            sender.forecolor = Color.Black
        End Sub
        Private Sub Bottone_MouseClick(sender As Object, e As System.EventArgs)
            Dim slctdBotton = TryCast(sender, Button)
            For i As Integer = 0 To Bottoni.Count - 1
                If sender.Text = Bottoni(i) Then Scelto = i + 1
            Next
        End Sub
    
    End Class
    

    giovedì 31 ottobre 2013 00:12
  • Non avevi aggiornato i ColumnStyles che rimanevano quelli di default (cioè 2 o quelli che sono nel tuo caso).

    Aggiungi le righe di seguito indicate dal commento AGGIUNGERE

    L'ultima colonna, in alcuni casi, può risultare leggermente più lunga delle altre. Dovrebbe essere un problema di arrotondamenti.

    Private Sub addButtons(ByVal tablelayoutpanel1 As TableLayoutPanel, ByVal bottoni As List(Of String), ByVal Scelto As Short) tablelayoutpanel1.ColumnStyles.Clear() ' <-- AGGIUNGERE Dim cs As ColumnStyle ' <-- AGGIUNGERE For i As Integer = 0 To tablelayoutpanel1.ColumnCount - 1 Dim Btn As New Button With Btn .Name = "Button" & i + 1 .Font = New System.Drawing.Font("Microsoft Sans Serif", 9.0!, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, CType(0, Byte)) .Text = bottoni(i) .Dock = DockStyle.Fill End With tablelayoutpanel1.Controls.Add(Btn) AddHandler Btn.MouseEnter, AddressOf Bottone_MouseEnter AddHandler Btn.MouseLeave, AddressOf Bottone_Mouseleave AddHandler Btn.MouseClick, AddressOf Bottone_MouseClick cs = New ColumnStyle ' <-- AGGIUNGERE tablelayoutpanel1.ColumnStyles.Add(cs) ' <-- AGGIUNGERE Next

    ...

    ...


    • Contrassegnato come risposta Matylda giovedì 31 ottobre 2013 08:51
    giovedì 31 ottobre 2013 07:08
  • Non avevi aggiornato i ColumnStyles che rimanevano quelli di default (cioè 2 o quelli che sono nel tuo caso).

    Aggiungi le righe di seguito indicate dal commento AGGIUNGERE

    L'ultima colonna, in alcuni casi, può risultare leggermente più lunga delle altre. Dovrebbe essere un problema di arrotondamenti.

    Private Sub addButtons(ByVal tablelayoutpanel1 As TableLayoutPanel, ByVal bottoni As List(Of String), ByVal Scelto As Short) tablelayoutpanel1.ColumnStyles.Clear() ' <-- AGGIUNGERE Dim cs As ColumnStyle ' <-- AGGIUNGERE For i As Integer = 0 To tablelayoutpanel1.ColumnCount - 1 Dim Btn As New Button With Btn .Name = "Button" & i + 1 .Font = New System.Drawing.Font("Microsoft Sans Serif", 9.0!, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, CType(0, Byte)) .Text = bottoni(i) .Dock = DockStyle.Fill End With tablelayoutpanel1.Controls.Add(Btn) AddHandler Btn.MouseEnter, AddressOf Bottone_MouseEnter AddHandler Btn.MouseLeave, AddressOf Bottone_Mouseleave AddHandler Btn.MouseClick, AddressOf Bottone_MouseClick cs = New ColumnStyle ' <-- AGGIUNGERE tablelayoutpanel1.ColumnStyles.Add(cs) ' <-- AGGIUNGERE Next

    ...

    ...


    Ti ringrazio per la soluzione del problema. Alla fine avevo capito che quello poteva essere il problema in quanto pur variando il numero delle colonne il numero dei ColumnStyle non variava ma non sapevo come aggiornarlo. Ora ho capito comr si fa.

    grazie matylda

     
    giovedì 31 ottobre 2013 08:57