Questo sito utilizza cookies, anche di terze parti, per mostrare pubblicità e servizi in linea con il tuo account. Leggi l'informativa sui cookies.
Username: Password: oppure
Guida al Visual Basic .NET - Il controllo BindingNavigator

Guida al Visual Basic .NET

Capitolo 76° - Il controllo BindingNavigator

<< Precedente Prossimo >>
Funzionamento

Questo controllo permette di navigare attraverso insiemi di dati, siano essi tabelle di database o semplici liste di oggetti non fa differenza, permettendo di visualizzare o modificare una qualsiasi delle loro proprietà e di aggiungere od eliminare uno qualsiasi dei suoi elementi. La particolarità che lo distingue da qualsiasi altro controllo del genere (come potrebbero essere ListView o DataGridView) consiste nel fatto che la sua interfaccia non è una tabella: anzi, è a priori indefinita. Se si considera poi il fatto che aggiungerlo semplicemente al form non porterà alcun risultato, si potrebbe pensare che BindingNavigator è proprio una fregatura XD
In effetti, per vederlo funzionare correttamente bisogna aggiungere un po' di altri controlli e scrivere qualche riga di codice. Infatti, ho appena detto che esso permette di navigare attraverso un insieme di dati e visualizzare tali dati su una certa interfaccia grafica che per ora non conosciamo: le incognite, quindi, sono due, ossia da dove attingere i dati e come visualizzarli. Per questo motivo, sono necessari almeno altri due componenti. Il primo di questi è un controllo BindingSource, il quale, come già visto nel capitolo precedente, si preoccupa di gestire e mediare l'interazione con una certa risorsa di informazioni. Il secondo (e gli altri eventuali) è arbitrario e dipende dalla natura dei dati da visualizzare: per delle stringhe, ad esempio, avremo bisogno di una TextBox.

Autori illustri...

Per esemplificare il comportamento di BindingNavigator, ecco una semplice applicazione che permette di visualizzare una serie di grandi nomi e le loro opere principali. La nostra fonte di dati sarà una lista di oggetti di tipo Author, classe così definita:

Public Class Form1

    Public Class Author
        Private _Name As String
        Private _Works As List(Of String)

        Public Property Name() As String
            Get
                Return _Name
            End Get
            Set(ByVal value As String)
                _Name = value
            End Set
        End Property

        Public ReadOnly Property Works() As List(Of String)
            Get
                Return _Works
            End Get
        End Property

        Public Sub New()
            _Works = New List(Of String)
        End Sub

        Public Sub New(ByVal Name As String, ByVal ParamArray WorksNames() As String)
            Me.New()
            Me.Name = Name
            Me.Works.AddRange(WorksNames)
        End Sub
    End Class

    Public Authors As New List(Of Author)

End Class

Ora aggiungiamo al form un BindingNavigator di nome bnMain:

BindingNavigator.jpg
All'aspetto sembra solo una toolstrip con qualche button, due label e una textbox. È questo, e anche di più.
Aggiungiamo ora un BindingSource di nome bsData e impostiamo la proprietà bsMain.BindingSource su bsData. Aggiungete altri controlli in modo che l'interfaccia sia la seguente:

BindingNavigator2.jpg
Vorremo usare il pulsanti freccia del binding navigator per spostarci avanti e indietro nella lista, e i rispettivi pulsanti per aggiungere o eliminare un elemento. Il codice:

Public Class Form1

    Public Class Author
        Private _Name As String
        Private _Works As List(Of String)

        Public Property Name() As String
            Get
                Return _Name
            End Get
            Set(ByVal value As String)
                _Name = value
            End Set
        End Property

        Public ReadOnly Property Works() As List(Of String)
            Get
                Return _Works
            End Get
        End Property

        Public Sub New()
            _Works = New List(Of String)
        End Sub

        Public Sub New(ByVal Name As String, ByVal ParamArray WorksNames() As String)
            Me.New()
            Me.Name = Name
            Me.Works.AddRange(WorksNames)
        End Sub
    End Class

    Public Authors As New List(Of Author)

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'Aggiungie alcuni elementi iniziali alla lista
        Authors.Add(New Author("Dante Alighieri", "Comed?a", "Vita Nova", "De vulgari eloquentia", "De Monarchia"))
        Authors.Add(New Author("Luigi Pirandello", "Il fu Mattia Pascal", "Uno, nessuno, centomila", "Il gioco delle parti"))
        'Imposta la sorgente di dati del bindingsource
        bsAuthors.DataSource = Authors

        'Aggiunge un binding alla textbox. Ciò significa
        'che la proprietà Text di txtName sarà da
        'ora in poi sempre legata alla proprietà Name
        'dell'elemento corrente della sorgente di dati di
        'bsAuthors. Dato che quest'ultima è una lista di
        'Author, ogni suo elemento espone la proprietà
        'Name.
        txtName.DataBindings.Add("Text", bsAuthors, "Name")
        
        'Non possiamo fare la stessa cosa con lstWorks.Items,
        'poiché Items è una proprietà readonly.
        'Questo capita abbastanza spesso: si ha bisogno di
        'visualizzare una lista per ogni elemento dell'insieme.
        'La soluzione consiste nel caricare gli items della
        'lista quando viene caricato un nuovo elemento
    End Sub

    Private Sub bsAuthors_CurrentChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bsAuthors.CurrentChanged
        'L'evento CurrentChanged si verifica quando la proprietà
        'Current del binding source viene modificata. Ciò significa
        'che l'utente si è spostato tramite il binding
        'navigator. Ottenendo l'oggetto Current, possiamo risalire alla
        'lista di stringhe che esso contiene
        Dim Author As Author = bsAuthors.Current
        lstWorks.Items.Clear()
        lstWorks.Items.AddRange(Author.Works.ToArray())
    End Sub

    Private Sub btnAdd_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAdd.Click
        'Aggiunge alla listbox e alla lista Works un nuovo
        'titolo aggiunto dall'utente
        If Not String.IsNullOrEmpty(txtAdd.Text) Then
            lstWorks.Items.Add(txtAdd.Text)
            DirectCast(bsAuthors.Current, Author).Works.Add(txtAdd.Text)
            txtAdd.Text = ""
        End If
    End Sub

    Private Sub btnDelete_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDelete.Click
        'Elimina una delle opere visualizzate
        If lstWorks.SelectedIndex >= 0 Then
            DirectCast(bsAuthors.Current, Author).Works.RemoveAt(lstWorks.SelectedIndex)
            lstWorks.Items.RemoveAt(lstWorks.SelectedIndex)
        End If
    End Sub
End Class

Come vedete, il codice è molto ridotto anche se l'applicazione supporta un numero più elevato di funzionalità: tutto ciò che non abbiamo scritto viene automaticamente gestito dal BindingNavigator.
La proprietà DataBindings, per inciso, non appartiene solo a TextBox, ma a tutti i controlli e non è necessario specificare come sorgente di dati un binding source, ma un qualsiasi oggetto, poiché tutto viene gestito tramite reflection. È possibile associare una qualsiasi proprietà di un controllo ad un campo di un qualsiasi altro oggetto.
Allo stesso modo, è possibile associare alla proprietà DataSource di BindingSource una tabella di un database, o un dataset (e associate un dataset, dovrebe usare la proprietà DataMember per specificare quale tabella).

<< Precedente Prossimo >>
A proposito dell'autore

Programmatore e analista .NET 2005/2008/2010 (in particolare C# e VB.NET), anche nell'implementazione Mono per Linux. Conoscenze approfondite di Pascal, PHP, XML, HTML 4.01/5, CSS 2.1/3, Javascript (e jQuery). Conoscenze buone di C, LUA, GML, Ruby, XNA, AJAX e Assembly 68000. Competenze basilari di C++, SQL, Hlsl, Java.