+ Rispondi al Thread
Visualizzazione dei risultati da 1 a 1 su 1

Discussione: FAQ Controlli

  1. #1
    L'avatar di elisab
    elisab non è in linea Very Important Person
    Post
    1,750

    FAQ Controlli

    Questa discussione raccoglie alcune delle domande frequenti relative ai controlli in generale.
    La lista è incompleta e verrà migliorata e aggiornata nel tempo.

    1. Aggiungere e rimuovere un controllo e relativi eventi a run-time
    2. Scorrere i controlli sul Form o in un contenitore
    3. Scorrere tutti i controlli sul Form (compresi quelli all'interno di un contenitore) con un algoritmo ricorsivo
    4. Conoscere il tipo di controllo per eseguire un'operazione su tutti i controlli di un certo tipo
    5. Condividere evento fra più controlli e sapere quale di questi ha sollevato l'evento
    6. Array di controlli
    7. Inserire controllo all'interno di un contenitore a run-time
    8. Consentire all'utente di spostare un controllo trascinandolo con il mouse



    Aggiungere e rimuovere un controllo e relativi eventi a run-time

    Per aggiungere un controllo ad un Form a run-time è necessario aggiungerlo alla collection Controls del Form.
    Con l'istruzione AddHandler si associa un evento (button.Click) a un gestore eventi (Button_Click) in fase di esecuzione.
    L'istruzione RemoveHandler rimuove l'associazione precedentemente creata.
    Per rimuovere il controllo dal form è necessario rimuoverlo dalla collection Controls del form a cui appartiene.

    codice:
    Public Class Form1
        Dim button As Button
    
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            button = New Button
    
            'posizione del controllo sul form
            button.Location = New Point(20, 20)
            'dimensioni del controllo
            button.Size = New Size(80, 50)
            button.Name = "Button1"
            button.Text = "Premi il pulsante"
    
            AddHandler button.Click, AddressOf Button_Click
    
            Me.Controls.Add(button)
        End Sub
    
        Private Sub Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
            MessageBox.Show(String.Format("Hai cliccato il button: {0}" & Environment.NewLine & _
                                          "Dopo aver premuto Ok verranno eliminati l'Handler e il pulsante", DirectCast(sender, Button).Name))
    
            RemoveHandler button.Click, AddressOf Button1_Click
            Me.Controls.Remove(button)
            'Me.Controls.RemoveByKey("Button1")
        End Sub
    
    End Class



    Scorrere i controlli sul Form o in un contenitore

    Per conoscere i controlli contenuti all'interno di un Form o di un contenitore è necessario scorrere la relativa collection Controls.

    Form: stampo nella finestra immediata il Name dei controlli all'interno del form ad esclusione di quelli inseriti in altri controlli, ad esempio quelli dentro i contenitori.
    codice:
            For Each ctrl As Control In Me.Controls
                Debug.WriteLine(ctrl.Name)
            Next

    Panel: stampo nella finestra immediata il Name dei controlli all'interno del Panel1 ad esclusione di quelli inseriti in altri controlli, ad esempio quelli dentro altri contenitori.
    codice:
            For Each ctrl As Control In Panel1.Controls
                Debug.WriteLine(ctrl.Name)
            Next



    Scorrere tutti i controlli sul Form (compresi quelli all'interno di un contenitore) con un algoritmo ricorsivo

    Con il seguente algoritmo ricorsivo è possibile conoscere non solo i controlli inseriti all'interno del Form, ma anche quelli all'interno di altri controlli come ad esempio i contenitori. La routine stampa il tipo e il nome di ogni controllo, i controlli contenuti in altri si trovano al di sotto dei contenitori in posizione rientrata.

    codice:
    System.Windows.Forms.Panel     Panel1
        System.Windows.Forms.Panel     Panel2
            System.Windows.Forms.ListBox     ListBox1
        System.Windows.Forms.Button     Button4
        System.Windows.Forms.Button     Button3
        System.Windows.Forms.TextBox     TextBox1
    System.Windows.Forms.TextBox     TextBox2
    System.Windows.Forms.TextBox     TextBox1
    System.Windows.Forms.Button     Button2
    System.Windows.Forms.Button     Button1
    codice:
        Private Sub GetControls(ByVal ctrl As Control)
    
            For Each c As Control In ctrl.Controls
    
                Debug.WriteLine(String.Format("{0}     {1}", c.GetType().ToString, c.Name))
    
                If c.Controls.Count > 0 Then
                    'aumento il livello di rientro nella finestra immediata
                    Debug.Indent()
    
                    GetControls(c)
    
                    'riduco il livello di rientro nella finestra immediata
                    Debug.Unindent()
                End If
    
            Next
        End Sub
    Uso
    codice:
    'ottengo tutti i controlli sul form
            GetControls(Me)
    
    'oppure ottengo tutti i controlli nel Panel1
            GetControls(Panel1)



    Conoscere il tipo di controllo per eseguire un'operazione su tutti i controlli di un certo tipo

    E' possibile conoscere il tipo di un controllo usando gli operatori TypeOf, TryCast o GetType.

    In tutti e tre gli esempi di codice scorro i controlli sul Form, verifico se il controllo è di tipo TextBox ed in caso affermativo cancello il contenuto.

    Nel caso in cui sia presente sul form un controllo che eredita da TextBox, usando TypeOf e TryCast per il controllo ereditato ottengo come tipo System.Windows.Forms.TextBox, mentre il metodo ctrl.GetType() retituisce come tipo SpazioDeiNomiRadice.Namespace.NomeControllo.

    codice:
            'Rileva il controllo da cui eredita
            For Each ctrl As Control In Me.Controls
                If TypeOf ctrl Is TextBox Then
                    Dim txt As TextBox = DirectCast(ctrl, TextBox)
                    txt.Clear()
                End If
            Next
    codice:
            'Rileva il controllo da cui eredita
            For Each ctrl As Control In Me.Controls
                Dim txt As TextBox = TryCast(ctrl, TextBox)
                If Not txt Is Nothing Then
                    txt.Clear()
                End If
            Next
    codice:
            For Each ctrl As Control In Me.Controls
                If ctrl.GetType() Is GetType(TextBox) Then
                    Dim txt As TextBox = DirectCast(ctrl, TextBox)
                    txt.Clear()
                End If
            Next



    Condividere evento fra più controlli e sapere quale di questi ha sollevato l'evento

    Per fare in modo che una stessa routine gestisca gli eventi generati da più controlli la firma della routine deve corrispondere alle firme di ciascun evento aggiunto.

    Per collegare routine ed eventi a run-time si utilizza l'istruzione AddHandler che consente di associare l'evento di più pulsanti allo stesso gestore di eventi (Button_Click). L'argomento sender restituito dal gestore di eventi Button_Click consente di capire quale controllo ha sollevato l'evento. Eseguendo il cast del sender sul tipo corretto di controllo sarà possibile accedere a tutte le proprietà ed i metodi che lo caratterizzano.

    codice:
    Public Class Form1
        
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            Dim button As Button
            Dim y As Integer = 20
    
            'aggiungo 4 pulsanti
            For i As Integer = 0 To 3
                button = New Button
    
                'posizione del controllo sul form
                button.Location = New Point(20, y)
                'dimensioni del controllo
                button.Size = New Size(120, 50)
                button.Name = "Button" & (i + 1).ToString
                button.Text = "Premi il pulsante " & button.Name
    
                AddHandler button.Click, AddressOf Button_Click
    
                Me.Controls.Add(button)
                y += (button.Size.Height + 5)
            Next
        End Sub
    
        Private Sub Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
    
            Dim btn As Button = DirectCast(sender, Button)
            MessageBox.Show(String.Format("Hai cliccato il button: {0}", btn.Name))
    
        End Sub
    
    End Class
    Se i controlli sono stati inseriti a design-time si può aggiungere l'evento del controllo (ad esempio Button2.Click) dopo la clausula Handles del gestore di eventi di uno dei controlli presenti (nell'esempio si sfrutta il gestore di eventi del Button1). Anche il questo caso bisognerà analizzare l'argomento sender per sapere quale controllo ha sollevato l'evento.
    codice:
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
                Handles Button1.Click, Button2.Click, Button3.Click
    
            Dim btn As Button = DirectCast(sender, Button)
            MessageBox.Show(String.Format("Hai cliccato il button: {0}", btn.Name))
    
        End Sub



    Array di controlli

    Non è possibile creare matrici di controlli a design-time, è però possibile ottenere da codice lo stesso risultato con due semplici operazioni.
    • Memorizzare i controlli che faranno parte dell'array in una matrice, Collection o Generic.List(Of <TipoControllo>).
    • Per ogni evento che deve essere scatenato, condividere il gestore di eventi con tutti i controlli dell'array.
    La matrice di controlli può essere creata sia per i controlli aggiunti a design-time che per quelli inseriti a run-time.

    In questo esempio inserisco nell'array tutti e quattro i Button aggiunti a run-time. Con l'istruzione AddHandler indirizzo l'evento Click di tutti i Button verso la stessa routine. Per eseguire un'operazione su tutti i controlli dell'array sarà sufficiente scorrere l'array e per accedere ad ogni controllo che lo compone.

    codice:
    Public Class Form1
        Dim buttArray() As Button
    
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            Dim button As Button
    
            Dim y As Integer = 20
    
            'aggiungo 4 pulsanti
            For i As Integer = 0 To 3
                button = New Button
    
                'posizione del controllo sul form
                button.Location = New Point(20, y)
                'dimensioni del controllo
                button.Size = New Size(120, 50)
                button.Name = "Button" & (i + 1).ToString
                button.Text = "Premi il pulsante " & button.Name
    
                AddHandler button.Click, AddressOf Button_Click
    
                Me.Controls.Add(button)
                y += (button.Size.Height + 5)
    
                'ridimensiono l'array
                Array.Resize(buttArray, i + 1)
                'aggiungo il button
                buttArray(i) = button
            Next
        End Sub
    
        Private Sub Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
            SetBackColor()
        End Sub
    
        Private Sub SetBackColor()
            For Each butt As Button In buttArray
                butt.BackColor = Color.Coral
            Next
        End Sub
    
    End Class



    Inserire controllo all'interno di un contenitore a run-time

    Per inserire un controllo all'interno di un contenitore è necessario impostare la proprietà Parent del controllo sul nuovo contenitore oppure aggiungere il controllo alla collection Controls del contenitore. Trasferendo un controllo dal Form ad un contenitore la proprietà Location del controllo non varia, per questo motivo il controllo inserito nel contenitore potrebbe non essere visibile, in questo caso è sufficiente modificare la proprietà Location.

    codice:
            PictureBox1.Parent = Panel1
            'oppure
            'Panel1.Controls.Add(PictureBox1)
    
            'reimposto la location
            PictureBox1.Location = New Point(10, 10)



    Consentire all'utente di spostare un controllo trascinandolo con il mouse

    Con il seguente esempio si consente all'utente di spostare, all'interno del Form, un controllo tenendo premuto il pulsante sinistro del mouse.

    codice:
    Public Class Form1
        Dim WithEvents PictureBox1 As New PictureBox
    
        'distanza fra il punto in cui si trova il puntatore quando inizio il trascinamento e
        'l'angolo superiore sinistro del PictureBox
        Dim cursorOffset As Point
    
        Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
            Me.Controls.Add(PictureBox1)
            PictureBox1.BackColor = Color.Red
        End Sub
    
        Private Sub PictureBox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown
            cursorOffset = e.Location
        End Sub
    
        Private Sub PictureBox1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove
    
            If e.Button = Windows.Forms.MouseButtons.Left Then
                'posizione del cursore rispetto al form
                Dim newLocation As Point = PointToClient(Cursor.Position)
                'coordinate dell'angolo superiore sinistro
                newLocation.Offset(-cursorOffset.X, -cursorOffset.Y)
    
                PictureBox1.Location = newLocation
            End If
    
        End Sub
    
    
    End Class
    Ultima modifica di elisab; 09-11-2011 01:16 
    Il Crossposting è vietato dalla Netiquette.

    Tutti gli utenti sono invitatati ad indicare nel titolo la versione di VB, Visual Studio o il Framework di compilazione.

    NB: In presenza del SyntaxHighlighter (codice colorato con numeri di riga a lato) prima di copiare il codice eseguire doppio click sulla finestra di codice, altrimenti mancheranno tutti i ritorno a capo.

+ Rispondi al Thread

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi