Oppure

Loading
20/09/14 10:42
xplosiv
Salve a tutti, e spero di riuscire a trovare un collega che mi aiuti a capire dove sbaglio, magari postando il sorgente completo (funzionante) oppure se molto gentile, e paziente, allegandomi un bell'allegato zip con il progetto completo. In definitiva, seguendo la guida di Totem, sulle Relazioni e passare di conseguenza all'utilizzo dei DataSet e dei DataTable con l'Adapter che mi permette di gestire tutti i records, non sono riuscito ad eseguire la gestione dell'evento per l'aggiunta di un Autore (O mi è sfuggito qualcosa o c'è qualcosa che non va!?) attraverso la creazione di un comodissimo User Control che ha un RaiseEvent e che in Runtime non mi viene richiamato! Comunque sia prima di postare il mio sorgente, voglio far presente che non ci sono Handles mancanti e penso di aver fatto tutte le dichiarazioni di classe ecc.

Questo il codice del Form1 (il Form principale :D)

Imports MySql.Data.MySqlClient
Imports DataSet_Tipizzati.AuthorViewer
Public Class Form1
    Private WithEvents avAuthor As New AuthorViewer

    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        Dim Conn As New MySqlConnection("server=localhost;database=appdata;user=root;password=miapassword;")
        Dim Adapter As New MySqlDataAdapter
        Conn.Open()

        'carica le tabelle nel dataset. Le tabelle sono ora
        'accessibili mediante omonime proprietà
        'dataset tipizzato

        Adapter.SelectCommand = New MySqlCommand("SELECT * FROM Songs;", Conn)
        Adapter.Fill(AppDataSet.Songs)

        Adapter.SelectCommand = New MySqlCommand("SELECT * FROM Authors;", Conn)
        Adapter.Fill(AppDataSet.Authors)

        Adapter.SelectCommand = New MySqlCommand("SELECT * FROM Albums;", Conn)
        Adapter.Fill(AppDataSet.Albums)


        Conn.Close()
    End Sub


    Private Sub lb_songs_SelectedIndexChanged(sender As System.Object, e As System.EventArgs) Handles lb_songs.SelectedIndexChanged
        If lb_songs.SelectedIndex < 0 Then
            Exit Sub
        End If

        'Trova la riga con ID specificato. Il tipo SongRow è stato
        'definito dall'IDE durante la creazione del dataset tipizzato.
        Dim S As AppDataSet.SongsRow = AppDataSet.Songs.FindByID(lb_songs.SelectedValue)

        lbName.Text = S.Title

        tabAuthor.Tag = Nothing
        'Anche il metodo IsAuthorNull è stato definito dall'IDE.
        'In generale, per ogni proprietà per cui non è stata
        'specificata la clausola NOT NULL, l'IDE crea un metodo per
        'verificare se quel dato attributo contiene un valore
        'nullo. Equivale a chamare S.IsNull(3).

        If Not S.IsAuthorNull() Then
            'Ottiene un array che contiene tutte le righe della
            'tabella Authors che soddisfano la relazione definita
            'tra Songs e Authors. Dato che la chiave esterna della tabella figlio era un ID,
            'la relazione, pur essendo tericamente uno-a-molti, è in realtà uno-a-uno. Perciò, se questo array
            'ha almeno un elemento, ne avrà solo uno.
            Dim Authors() As AppDataSet.AuthorsRow = S.GetAuthorsRows()
            'Come IsNull, questo metodo equivale a chiamare
            'S.GetChildRows("Songs_Authors")

            'Imposta la proprietà  Author del controllo avAuthor,
            'che non è altro che un'istanza di AuthorViewer,
            'il controllo utente crato ad hoc

            If Authors.Length > 0 Then
                Dim Author As AppDataSet.AuthorsRow = Authors(0)
                avAuthor.Author = Author
            Else
                avAuthor.Author = Nothing
            End If

        End If

        tabAlbum.Tag = Nothing
        If Not S.IsAlbumNull Then
            Dim Albums() As AppDataSet.AlbumsRow = S.GetAlbumsRows

            If Albums.Length > 0 Then
                Dim Album As AppDataSet.AlbumsRow = Albums(0)

                lbAlbumName.Text = Album.Name
                If Not Album.IsYearNull Then
                    lbYear.Text = Album.Year
                Else
                    lbYear.Text = ""
                End If
                If Not Album.IsImageNull Then
                    imgAlbum.Image = Image.FromFile(Album.Image)
                Else
                    imgAlbum.Image = Nothing
                End If
                If Not Album.IsDescriptionNull Then
                    tbAlbumDescription.Text = Album.Description
                Else
                    tbAlbumDescription.Text = ""
                End If
                tabAlbum.Tag = Album.ID
            End If
        End If
    End Sub


    Private Sub btSearch_Click(sender As System.Object, e As System.EventArgs) Handles btSearch.Click
        If Not String.IsNullOrEmpty(tbSearch.Text) Then
            'la proprietà Filter di un binding source è come
            'una condizione SQL. In questo caso cerchiamo tutte le
            'canzoni il cui titolo contenga la stringa specificata
            SongsBindingSource.Filter = String.Format("title like '%{0}%'", tbSearch.Text)
        Else
            SongsBindingSource.Filter = ""
        End If
    End Sub


    Private Sub avAuthor_AuthorAdded(sender As Object, e As System.EventArgs) Handles avAuthor.AuthorAdded
        If lb_songs.SelectedIndex < 0 Then
            Exit Sub
        End If

        Dim S As AppDataSet.SongsRow = AppDataSet.Songs.FindByID(lb_songs.SelectedValue)
        'imposta il campo Author della canzone corrente
        S.Author = avAuthor.Author.ID
    End Sub

    Private Sub Form1_FormClosing(sender As Object, e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
        Dim Conn As New MySqlConnection("server=localhost;database=appdata;user=root;password=miapassword;")
        Dim Adapter As New MySqlDataAdapter

        'Un oggetto di tipo CommandBuilder genera automaticamente
        'tutti le istruzioni update, INSERT IGNORE e delete che servono
        'a un adapter per funzionare. Tali istruzioni vengono
        'generate relativamente alla tabella dalla quale si stanno
        'caricando i dati
        Dim Builder As MySqlCommandBuilder

        Conn.Open()

        Adapter.SelectCommand = New MySqlCommand("SELECT * FROM Songs;", Conn)
        Builder = New MySqlCommandBuilder(Adapter)
        Adapter.Update(AppDataSet.Songs)

        Adapter.SelectCommand = New MySqlCommand("SELECT * FROM Authors;", Conn)
        Builder = New MySqlCommandBuilder(Adapter)
        Adapter.Update(AppDataSet.Authors)

        Adapter.SelectCommand = New MySqlCommand("SELECT * FROM Albums;", Conn)
        Builder = New MySqlCommandBuilder(Adapter)
        Adapter.Update(AppDataSet.Albums)

        Conn.Close()
    End Sub

End Class


E questo il codice del Controllo Utente (8-|)

Public Class AuthorViewer
    Private _Author As AppDataSet.AuthorsRow

    'Evento generato quando un autore viene aggiunto. Questo
    'evento si verifica se l'utente salva dei cambiamenti
    'quando la proprietà Author è Nothing.
    'Non potendo modificare una riga esistente, quindi, ne
    'viene creata una nuova. Poichè, tuttavia, questo
    'autore deve essere associato alla canzone,
    'bisogna che qualcuno ponga l'ID della nuova riga nel campo
    'Author della canzone opportuna e, dato che questo controllo non può
    'ne logicamente ne praticamente arrivare a fare ciò, bisogna che
    'qualcun altro se ne occupi.

    Public Event AuthorAdded As EventHandler

    Public Property Author() As AppDataSet.AuthorsRow
        Get
            Return _Author
        End Get
        Set(value As AppDataSet.AuthorsRow)
            If value IsNot Nothing Then
                _Author = value
                With value
                    lbName.Text = .Name
                    If Not .IsImageNull Then
                        imgAuthor.ImageLocation = .Image
                    Else
                        imgAuthor.ImageLocation = Nothing
                    End If
                    If Not .IsDescriptionNull Then
                        tbDescription.Text = .Description
                    Else
                        tbDescription.Text = ""
                    End If
                    imgSave.Visible = False
                End With
            Else
                lbName.Text = "Nessun nome"
                imgAuthor.ImageLocation = Nothing
                tbDescription.Text = ""
            End If
        End Set
    End Property

    Private Sub imgAuthor_Click(sender As System.Object, e As System.EventArgs) Handles imgAuthor.Click
        'FOpen è un OpenFileDialog dichiarato nel designer.
        'Questo codice serve per caricare un'immagine da disco fisso
        If FOpen.ShowDialog = DialogResult.OK Then
            imgAuthor.ImageLocation = FOpen.FileName
            imgSave.Visible = True
        End If
    End Sub

    'L'immagine del floppy diventa visibile solo quando c'è stata
    'una modifica, ossia è stato cambiato uno di questi parametri:
    'nome, immagine, descrizione.

    Private Sub tbDescription_TextChanged(sender As System.Object, e As System.EventArgs) Handles tbDescription.TextChanged
        imgSave.Visible = True
    End Sub

    Private Sub lbName_Click(sender As System.Object, e As System.EventArgs) Handles lbName.Click
        Dim NewName As String = InputBox("Inserire nome:")

        If Not String.IsNullOrEmpty(NewName) Then
            lbName.Text = NewName
            imgSave.Visible = True
        End If
    End Sub

    Private Sub imgSave_Click(sender As System.Object, e As System.EventArgs) Handles imgSave.Click
        If _Author Is Nothing Then
            'Crea la nuova riga e la inserisce nel dataset
            'principale.
            _Author = My.Forms.Form1.AppDataSet.Authors.AddAuthorsRow(lbName.Text, "", tbDescription.Text, imgAuthor.ImageLocation)
            'Genera l'evento AuthorAdded
            RaiseEvent AuthorAdded(Me, EventArgs.Empty)
        Else
            _Author.Name = lbName.Text
            _Author.Description = tbDescription.Text
            _Author.Image = imgAuthor.ImageLocation
        End If
        imgSave.Visible = False
    End Sub
End Class


:hail::hail::hail: Grazie Mille a Tutti!!!!! ;)
Ultima modifica effettuata da xplosiv 20/09/14 11:14
aaa
20/09/14 16:50
Ultimo
Nella guida il Totem ha scritto "Conn.Clone()" tu hai messo " Conn.Close()"
Ultima modifica effettuata da Ultimo 20/09/14 16:52
If ok Then GOTO Avanza else GOTO Inizia

20/09/14 17:16
xplosiv
Postato originariamente da Ultimo:

Nella guida il Totem ha scritto "Conn.Clone()" tu hai messo " Conn.Close()"


Grazie Ultimo per la tua risposta, ma non è stata proficua, in quanto anche se utilizzo il membro della MySqlConnection "Clone()" non succede alcun che! 8-|

Io ho utilizzato il membro Close() per chiudere la connessione con il database una volta caricato i dati sul DataSet, e una volta che viene chiusa l'applicazione!

Il mio problema, purtroppo, rimane ancora vivo! :d

Questo sorgente, dovrebbe, per come ho capito, utilizzare l'approccio standard, con le classi DataSet e DataTable, che rappresentano esattamente il database, con tutte le sue proprietà e caratteristiche, e grazie a questo, creare le righe della tabella chiamata in causa, nel caso specifico la tabella Author e per la quale viene aggiunto, grazie al Controllo Utente creato, un nuovo Autore ogni volta che si inseriscono i record per quella tabella e attraverso il click su un button viene aggiornato il DataSet!
Sin qui tutto ok! :k:
Ma quando si fa click sul tasto, dovrebbe scatenare l'evento AuthorAdded
Cioè:

RaiseEvent AuthorAdded(Me, EventArgs.Empty)


per fare in modo di assegnare, grazie alla relazione tra le tabelle, l'ID dell'Autore, alla canzone che viene selezionata nella ListView:

Private Sub avAuthor_AuthorAdded(sender As Object, e As System.EventArgs) Handles avAuthor.AuthorAdded
        If lb_songs.SelectedIndex < 0 Then
            Exit Sub
        End If

        Dim S As AppDataSet.SongsRow = AppDataSet.Songs.FindByID(lb_songs.SelectedValue)
        'imposta il campo Author della canzone corrente
        S.Author = avAuthor.Author.ID
    End Sub


Ma alla fin fine! Niente ID nella Tabella Songs che sfortunatamente rimane con il (NULL) presente nella riga! :om:
aaa
20/09/14 17:25
xplosiv
Giusto per capire posto anche questo bel ScreenShot della tabella su SQLyog, giusto per capire meglio il risultato non ottenuto:

aaa
20/09/14 18:04
Ultimo
Forse hai saltato qualcosa, rileggilo
If ok Then GOTO Avanza else GOTO Inizia

20/09/14 19:00
xplosiv
Postato originariamente da Ultimo:

Forse hai saltato qualcosa, rileggilo


No non credo! È già 3 giorni che mi scervello, ma non trovo ciò che manca! L'avró letto almeno 100 volte, e lo conosco a memoria! Mi sa che ci rinuncio! Più che altro mi serviva fare un po' di ripasso per una selezione a fine mese!

Grazie comunque.
aaa
20/09/14 21:51
Ultimo
prova a zippare il sources, lo provo e vedo dove sbagli
If ok Then GOTO Avanza else GOTO Inizia

20/09/14 23:17
xplosiv
Ok, scusa Ultimo se posto solo ora, ma ero fuori casa! Qui è piena estate ancora, come penso anche li da te! :D

Vedi un po'!
aaa