Auteur de questions
Ajouter un enregistrement avec bindingsource

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 SubQuand 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
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 -
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 -
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. -
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.