none
Ajouter un enregistrement avec bindingsource RRS feed

  • Discussion générale

  • Bonjour,

    Mon application affiche les enregistrements d'une base de données pour permettre d'ajouter, modifier, supprimer des enregistrements.

    Dans ma form, il y a à gauche un contrôle listbox (nommé lstRecords) qui affiche la liste des personnes dans le dataset. À droite, des contrôles affichent les champs d'information pour la personne choisie dans la listbox.

    La listbox et les contrôles sont "bindés" au dataset via un objet bindingsource (nommé m_bs). Lorsque l'item sélectionné dans la listbox change, les contenus des contrôles à droite se mettent à jour automatiquement. Jusque là, tout fonctionne correctement.

    Mon problème concerne l'ajout d'un enregistrement. Voici mon code pour l'instant :

    Private Sub RecordNew(ByVal sender As Object, ByVal e As System.EventArgs) _
                              Handles msiRecordNew.Click, tsiRecordNew.Click
        m_bs.AddNew()
        lstRecords.SelectedIndex = m_bs.Count - 1
    End Sub

    Quand je choisis un item dans la listbox, les contrôles se mettent à jour automatiquement à droite. Si j'ajoute un nouvel enregistrement, je constate qu'un nouvel item sans texte a été ajouté à la fin de la listbox, mais les données à droite ne se mettent pas à jour. Les données de l'enregistrement précédent y restent visibles.

    Puisque le nouvel enregistrement a des valeurs 'vides', je m'attendrais à ce que les contrôles se vident d'eux-mêmes, prêts à recevoir les nouvelles données.

    Qu'est-ce que je n'ai pas compris?

    Merci!

    • Type modifié Aurel Bera jeudi 17 juillet 2014 13:50 disc
    jeudi 10 juillet 2014 19:05

Toutes les réponses

  • Bonjour,

    Pouvez-vous nous soumettre un petit projet qui reproduirait le problème ? Car j'ai du mal à voir d'où pourrait venir le problème...

    Cordialement


    Gilles TOURREAU - MVP C#
    Architecte logiciel/Consultant/Formateur Freelance - P.O.S Informatique
    Blog : http://gilles.tourreau.fr - Suivez-moi sur Twitter
    - MCPD : Enterprise Developper / Windows Developper 3.5 / ASP .NET 3.5/4.0
    - MCSA : SQL Server 2012
    - MCITP : SQL Server 2008 Developper
    - MCTS : ADO .NET 3.5 / SQL Server 2008 Developper / Windows Forms 3.5 / ASP .NET 3.5/4.0 / TFS 2010 / Windows Azure

    jeudi 10 juillet 2014 20:19
    Modérateur
  • Bonjour Gilles,

    Voici mon code actuel.

    Merci pour toute aide.

    Option Strict Off

    Imports System
    Imports System.Data
    Imports System.Data.OleDb

    Public Class FMain

    #Region "Déclarations"

        Public Options As COptions

        Private m_connString As String
        Private m_conn As OleDbConnection
        Private m_da As OleDbDataAdapter
        Private m_ds As DataSet
        Private WithEvents m_bs As BindingSource

    #End Region

    #Region "Événements de Form"

        Private Sub FMain_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    ' Code pour récupérer les options dans l'objet Options.
            If CreateDataset() Then
                Me.Text = " " & My.Application.Info.ProductName
                SetBindings()
            Else
                MessageBox.Show("L'application ne peut pas démarrer parce que les données ne sont pas
                                              accessibles.", _
                                               Me.Text, MessageBoxButtons.OK, MessageBoxIcon.Error)
                End
            End If
        End Sub

    #End Region

    #Region "Événements de MenuStrip et ToolStrip"

        Private Sub EditionFind(ByVal sender As Object, ByVal e As System.EventArgs) Handles msiEditionFind.Click
            tsiFindBox.Focus()
        End Sub

        Private Sub RecordNew(ByVal sender As Object, ByVal e As System.EventArgs) _
                              Handles msiRecordNew.Click, tsiRecordNew.Click
            m_bs.AddNew()
            lstRecords.SelectedIndex = m_bs.Count - 1
        End Sub

        ' Code pour les autres commandes de MenuStrip et ToolStrip

    #End Region

    #Region "Événements des contrôles"

        Private Sub Control_Leave(ByVal sender As Object, ByVal e As System.EventArgs) _
                                  Handles txtPrenom.Leave, txtNom.Leave, txtLocalite.Leave
            Dim ctrl As TextBox = DirectCast(sender, TextBox)
            If (ctrl.Name = "txtPrenom") OrElse (ctrl.Name = "txtNom") OrElse (ctrl.Name = "txtLocalite") Then
                Try
                    App.FixText(ctrl)     ' Code pour standardiser le text saisi
                Catch ex As Exception
                    MessageBox.Show(ex.Message, "Attention")
                    ctrl.Focus()
                End Try
            End If
        End Sub

        Private Sub Control_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) _
                                        Handles txtPrenom.TextChanged, txtNom.TextChanged
            txtClasserSous.Text = txtNom.Text & ", " & txtPrenom.Text
        End Sub

        Private Sub Fonction_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) _
                                                  Handles cboFonction.SelectedIndexChanged
            Select Case cboFonction.Text
                Case "Président", "Présidente"
                    txtCodeFonction.Text = "1"
                    ckbExecutif.Checked = True
                Case "Vice-président", "Vice-présidente"
                    txtCodeFonction.Text = "2"
                    ckbExecutif.Checked = True
                Case "Secrétaire"
                    txtCodeFonction.Text = "3"
                    ckbExecutif.Checked = True
                Case "Trésorier", "Trésorière"
                    txtCodeFonction.Text = "4"
                    ckbExecutif.Checked = True
                Case "Administrateur", "Administratrice"
                    txtCodeFonction.Text = "5"
                    ckbExecutif.Checked = False
                Case Else
                    txtCodeFonction.Text = "0"
                    ckbExecutif.Checked = False
            End Select
        End Sub

        Private Sub Titre_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) _
                                               Handles cboTitre.SelectedIndexChanged
            SetFonctionList(cboTitre.Text)
        End Sub

    #End Region

    #Region "Implémentation privée"

        ' Créer le dataset qui contient les données utilisées par l'application.
        ' Les données proviennent d'une base de données Access.
        ' Le nom de la base de données est renseigné dans une constante déclarée dans le module MGlobal.
        Private Function CreateDataset() As Boolean
            Dim strSelect As String = "SELECT * FROM Membres"
            m_connString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & _
                           IO.Path.Combine(Me.Options.PathData, DATABASE_NAME) & ";" & _
                           "Persist Security Info=False;User Id=Admin;Password=;"
            Try
                m_conn = New OleDbConnection(m_connString)
                m_da = New OleDbDataAdapter(strSelect, m_conn)
                m_ds = New DataSet
                m_da.Fill(m_ds)
                Return True
            Catch ex As OleDbException
                MessageBox.Show("Un problème empêche l'ouverture de la base de données " & DATABASE_NAME &
                                               "." &  vbCrLf & ex.Message, "Erreur", MessageBoxButtons.OK, _
                                                  MessageBoxIcon.Error)
                Return False
            End Try
        End Function

        ' Rechercher un item dans lstRecords.
        ' lstRecords contient le champ ClasserSous (Nom, Prénom).
        ' On peut chercher une chaîne de caractères située n'importe où dans un item de lstRecords.
        Private Sub EditionFind()
            Dim strFind As String = tsiFindBox.Text
            Dim strFindUpper As String = strFind.ToUpper
            Dim intFound As Integer
            tsiFindBox.Clear()
            ' Vérifier si une valeur de recherche a été entrée.
            If strFind = String.Empty Then
                MessageBox.Show("Vous devez fournir la chaîne de caractères à rechercher.", " Rechercher", _
                                MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
                tsiFindBox.Focus()
                Exit Sub
            End If
            ' Faire la recherche.
            intFound = -1
            For i As Int32 = 0 To m_bs.Count - 1
                Dim strClasserSous As String = m_bs.Item(i).Item("ClasserSous")
                strClasserSous = strClasserSous.ToUpper
                If strClasserSous.Contains(strFindUpper) Then
                    intFound = i
                    Exit For
                End If
            Next
            If intFound = -1 Then
                MessageBox.Show("'" & strFind & "' inexistant.", " Rechercher", MessageBoxButtons.OK, _
                                MessageBoxIcon.Exclamation)
                tsiFindBox.Focus()
            Else
                With lstRecords
                    .TopIndex = intFound
                    .SelectedIndex = intFound
                    .Focus()
                End With
            End If
        End Sub

        ' Récupérer la valeur du champ ID de la base de données pour l'enregistrement qui vient d'être ajouté.

        ' Je prévois m'en servir au moment d'enregistrer le nouvel enregistrement.
        Private Function GetNewID() As String
            Dim conn As New OleDbConnection(m_connString)
            Dim cmd As New OleDbCommand
            Dim strID As String
            Try
                conn.Open()
                cmd.Connection = conn
                cmd.CommandText = "SELECT MAX(ID) FROM Membres"
                Dim dr As OleDbDataReader = cmd.ExecuteReader
                dr.Read()
                strID = dr.Item(0).ToString
            Catch ex As Exception
                strID = "0"
            Finally
                If conn.State = ConnectionState.Open Then
                    conn.Close()
                End If
                cmd = Nothing
                conn = Nothing
            End Try
            Return strID
        End Function

        ' Lier les contrôles aux colonnes de m_bs.
        Private Sub SetBindings()
            m_bs = New BindingSource
            With m_bs
                .DataSource = m_ds
                .DataMember = m_ds.Tables(0).ToString
                .Sort = "ClasserSous"
            End With
            With lstRecords
                .DataSource = m_bs
                .DisplayMember = "ClasserSous"
            End With
            cboTitre.DataBindings.Add("Text", m_bs, "Titre")
            txtPrenom.DataBindings.Add("Text", m_bs, "Prenom")
            txtNom.DataBindings.Add("Text", m_bs, "Nom")
            txtAdresse1.DataBindings.Add("Text", m_bs, "Adresse1")
            txtLocalite.DataBindings.Add("Text", m_bs, "Localite")
            cboProvince.DataBindings.Add("Text", m_bs, "Province")
            txtCodePostal.DataBindings.Add("Text", m_bs, "CodePostal")
            txtLibTelephone1.DataBindings.Add("Text", m_bs, "LibTelephone1")
            mtbTelephone1.DataBindings.Add("Text", m_bs, "Telephone1")
            mtbPosteTel1.DataBindings.Add("Text", m_bs, "PosteTel1")
            txtLibTelephone2.DataBindings.Add("Text", m_bs, "LibTelephone2")
            mtbTelephone2.DataBindings.Add("Text", m_bs, "Telephone2")
            mtbPosteTel2.DataBindings.Add("Text", m_bs, "PosteTel2")
            txtLibTelephone3.DataBindings.Add("Text", m_bs, "LibTelephone3")
            mtbTelephone3.DataBindings.Add("Text", m_bs, "Telephone3")
            mtbPosteTel3.DataBindings.Add("Text", m_bs, "PosteTel3")
            txtLibTelephone4.DataBindings.Add("Text", m_bs, "LibTelephone4")
            mtbTelephone4.DataBindings.Add("Text", m_bs, "Telephone4")
            mtbPosteTel4.DataBindings.Add("Text", m_bs, "PosteTel4")
            txtLibTelephone5.DataBindings.Add("Text", m_bs, "LibTelephone5")
            mtbTelephone5.DataBindings.Add("Text", m_bs, "Telephone5")
            mtbPosteTel5.DataBindings.Add("Text", m_bs, "PosteTel5")
            txtAdresseCourriel.DataBindings.Add("Text", m_bs, "AdresseCourriel")
            txtAdresseWeb.DataBindings.Add("Text", m_bs, "AdresseWeb")
            cboFonction.DataBindings.Add("Text", m_bs, "Fonction")
            txtFinMandat.DataBindings.Add("Text", m_bs, "FinMandat")
            txtOccupation.DataBindings.Add("Text", m_bs, "Occupation")
            txtNotes.DataBindings.Add("Text", m_bs, "Notes")
            txtClasserSous.DataBindings.Add("Text", m_bs, "ClasserSous")
            txtCodeFonction.DataBindings.Add("Text", m_bs, "CodeFonction")
            ckbExecutif.DataBindings.Add("Checked", m_bs, "Executif")
            txtID.DataBindings.Add("Text", m_bs, "ID")
        End Sub

        ' Fixer les valeurs proposées par le ComboBox cboFonction selon le sexe de la personne.
        Private Sub SetFonctionList(ByVal strTitre As String)
            If strTitre = "Madame" Then
                With cboFonction.Items
                    .Clear()
                    .Add("Présidente")
                    .Add("Vice-présidente")
                    .Add("Secrétaire")
                    .Add("Trésorière")
                    .Add("Administratrice")
                End With
            ElseIf strTitre = "Monsieur" Then
                With cboFonction.Items
                    .Clear()
                    .Add("Président")
                    .Add("Vice-président")
                    .Add("Secrétaire")
                    .Add("Trésorier")
                    .Add("Administrateur")
                End With
            Else
                cboFonction.Items.Clear()
            End If
        End Sub

    #End Region

    End Class

    vendredi 11 juillet 2014 15:19
  • Bonjour

    Comme Gilles  vous a indiqué, sera plus simple de créer un petit projet de teste et le partager avec nous.
    Avec le code, ça vas prendre des longues heures pour ajouter tous les contrôles dont on a besoin.
    De l'autre cote, je viens de faire un petit teste très simple, et après l'ajout d'une nouvelle ligne le DataBinding fonctionne correctement. 

    Bien cordialement, 


    Aurel BERA, MSFT
    MSDN Community Support. LE CONTENU EST FOURNI "TEL QUEL" SANS GARANTIE D'AUCUNE SORTE, EXPLICITE OU IMPLICITE.
    S'il vous plaît n'oubliez pas de "Marquer comme réponse" les réponses qui ont résolu votre problème. C'est une voie commune pour reconnaître ceux qui vous ont aidé, et rend plus facile pour les autres visiteurs de trouver plus tard la résolution.

    mardi 15 juillet 2014 08:34
  • Bonjour,

    J'ai créé un petit projet comme vous l'avez demandé avec l'intention de vous l'envoyer. En testant ce projet, je constate que tout fonctionne correctement comme prévu lorsque j'utilise la méthode BindingSource.AddNew. Il n'est donc pas nécessaire que j'envoie ce projet.

    Je vais recréer morceau par morceau le projet qui pose problème. Je verrai bien où ça accroche.

    Considérons le sujet clos.

    Merci.

    jeudi 17 juillet 2014 17:20