Hej! Kan du inte lägga upp lite kod till detta så blir problemställningen lite tydligare. Hej Magnus Hej! Hej Jonas!Problem med bundna comboboxar (nu med exempelkod)
Problemet blir kanske lite lättare att förstå med lite exempelkod (jag vet, den ser ut som kriget men det är ett hastigt hopplock för att slippa skicka med hela koden). Det kan vara en bra idé att ändra connectionstring till något som passar er miljö.
SelectedValueChanged körs vid initsiering av combon vilket ju är helt korrekt. SelectedValueChanged körs däremot inte när man bläddrar mellan posterna och värdet helt uppenbart förändras (by design?). Det intressanta börjar när man klickar 'New'. Jag sätter ett defaultvärde i kod, i detta fall 13 som motsvarar 'Konbu'. SelectedValueChanged körs då inte (by design?). Comboboxen visar rätt värde men i datasetet finns inte denna förändring registrerad vilket man kan se genom att klicka 'HasChanges?'. När EndCurrentEdit körs före mDs.HasChanges så försvinner dock förändringen vilket är lite märkligt eftersom ingenting är ändrat... eller? För att datasetet ska innehålla ProductId = 13 måste jag aktivt klicka i comboboxen och välja 'Konbu'. Först då körs SelectedValueChanged och förändringen finns med i dataset:et. Alltså är det egentligen två problem. SelectedValueChanged är inte konsekvent eftersom den barar triggas vid klickning eller vid initsiering, dock inte när man sätter SelectedValue i kod. Problem två är att datasetet inte förändras om man sätter SelectedValue i kod utan man måste klicka och välja istället. Att sedan EndCurrentEdit sållar bort förändringen om man inte klickat gör mig bara mer förvirrad.
Ett tips för att enkelt se skillnaden. Bläddra mellan posterna tills Combons värde ändras. SelectedValueChanged körs inte. Klicka på 'New', skriv ett värde i OrderId och sedan på 'HasChanges?'. Datasetet innehåller bara OrderId. Starta om programmet. Gör samma sak som ovan fast. Kontollera att det står 'Konfu' i combon efter man tryckt 'New'. Välj sedan 'Konfu' igen genom att klicka fram värdet. Poff! SelectedValueChanges körs (eh jaha, har värdet förändrats?). Klicka 'HasChanges?' - förändringen finns med... Jag är förvirrad!
Jag reserverar mig för att jag kanske gör något fundamentalt fel men det känns faktiskt som en bugg. Jag har inte testat exakt denna kod i VB.NET 2002 utan bara i 2003-betan.
MVH
Magnus
<code>
Imports System.Data.SqlClient
Imports System.Data.Common
Public Class Form1
Inherits System.Windows.Forms.Form
Private mCM As CurrencyManager
Private mDs As New DataSet
Private mbBuf As Boolean
#Region " Windows Form Designer generated code "
Public Sub New()
MyBase.New()
'This call is required by the Windows Form Designer.
InitializeComponent()
'Add any initialization after the InitializeComponent() call
End Sub
'Form overrides dispose to clean up the component list.
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub
'Required by the Windows Form Designer
Private components As System.ComponentModel.IContainer
'NOTE: The following procedure is required by the Windows Form Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
Friend WithEvents ComboBox1 As System.Windows.Forms.ComboBox
Friend WithEvents TextBox1 As System.Windows.Forms.TextBox
Friend WithEvents Button2 As System.Windows.Forms.Button
Friend WithEvents btnPrev As System.Windows.Forms.Button
Friend WithEvents btnNext As System.Windows.Forms.Button
Friend WithEvents TextBox2 As System.Windows.Forms.TextBox
Friend WithEvents btnHasChanges As System.Windows.Forms.Button
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
Me.ComboBox1 = New System.Windows.Forms.ComboBox
Me.TextBox1 = New System.Windows.Forms.TextBox
Me.btnHasChanges = New System.Windows.Forms.Button
Me.Button2 = New System.Windows.Forms.Button
Me.btnPrev = New System.Windows.Forms.Button
Me.btnNext = New System.Windows.Forms.Button
Me.TextBox2 = New System.Windows.Forms.TextBox
Me.SuspendLayout()
'
'ComboBox1
'
Me.ComboBox1.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList
Me.ComboBox1.Location = New System.Drawing.Point(96, 48)
Me.ComboBox1.Name = "ComboBox1"
Me.ComboBox1.Size = New System.Drawing.Size(121, 21)
Me.ComboBox1.TabIndex = 0
'
'TextBox1
'
Me.TextBox1.Location = New System.Drawing.Point(24, 16)
Me.TextBox1.Name = "TextBox1"
Me.TextBox1.Size = New System.Drawing.Size(120, 20)
Me.TextBox1.TabIndex = 1
Me.TextBox1.Text = ""
'
'btnHasChanges
'
Me.btnHasChanges.Location = New System.Drawing.Point(136, 120)
Me.btnHasChanges.Name = "btnHasChanges"
Me.btnHasChanges.Size = New System.Drawing.Size(88, 23)
Me.btnHasChanges.TabIndex = 2
Me.btnHasChanges.Text = "HasChanges?"
'
'Button2
'
Me.Button2.Location = New System.Drawing.Point(48, 120)
Me.Button2.Name = "Button2"
Me.Button2.TabIndex = 3
Me.Button2.Text = "New"
'
'btnPrev
'
Me.btnPrev.Location = New System.Drawing.Point(80, 80)
Me.btnPrev.Name = "btnPrev"
Me.btnPrev.TabIndex = 4
Me.btnPrev.Text = "Previous"
'
'btnNext
'
Me.btnNext.Location = New System.Drawing.Point(168, 80)
Me.btnNext.Name = "btnNext"
Me.btnNext.TabIndex = 5
Me.btnNext.Text = "Next"
'
'TextBox2
'
Me.TextBox2.Location = New System.Drawing.Point(152, 16)
Me.TextBox2.Name = "TextBox2"
Me.TextBox2.TabIndex = 6
Me.TextBox2.Text = ""
'
'Form1
'
Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
Me.ClientSize = New System.Drawing.Size(344, 166)
Me.Controls.Add(Me.TextBox2)
Me.Controls.Add(Me.btnNext)
Me.Controls.Add(Me.btnPrev)
Me.Controls.Add(Me.Button2)
Me.Controls.Add(Me.btnHasChanges)
Me.Controls.Add(Me.TextBox1)
Me.Controls.Add(Me.ComboBox1)
Me.Name = "Form1"
Me.Text = "Form1"
Me.ResumeLayout(False)
End Sub
#End Region
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
Try
Dim xDAL As New DAL
Dim dsProducts As DataSet
xDAL.OpenConnection()
mDs = xDAL.SelectOrderDetails
dsProducts = xDAL.SelectProducts
xDAL.CloseConnection()
mbBuf = True
With ComboBox1
.DataSource = dsProducts.Tables("PRODUCTS")
.DisplayMember = "ProductName"
.ValueMember = "ProductID"
End With
mbBuf = False
TextBox1.DataBindings.Add("Text", mDs, "OrderDetails.OrderID")
ComboBox1.DataBindings.Add("SelectedValue", mDs, "OrderDetails.ProductID")
mCM = Me.BindingContext(mDs, "OrderDetails")
AddHandler mCM.PositionChanged, AddressOf PositionChanged
Catch ex As Exception
MessageBox.Show(ex.ToString)
End Try
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
mCM.AddNew()
'SelectedValueChange triggas inte!
ComboBox1.SelectedValue = 13 ' Default = 'Konbu'
End Sub
Private Sub btnNext_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnNext.Click
If mCM.Position < mCM.Count Then
mCM.Position += 1
End If
End Sub
Private Sub btnPrev_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPrev.Click
If mCM.Position > 1 Then
mCM.Position -= 1
End If
End Sub
Private Sub PositionChanged(ByVal sender As Object, ByVal e As EventArgs)
TextBox2.Text = mCM.Position.ToString
End Sub
Private Sub ComboBox1_SelectedValueChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectedValueChanged
If mbBuf Then Exit Sub
MessageBox.Show("SelectedValueChanged")
End Sub
Private Sub btnHasChanges_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnHasChanges.Click
mCM.EndCurrentEdit()
If mDs.HasChanges Then
MessageBox.Show(mDs.GetChanges.GetXml)
Else
MessageBox.Show("HasChanges = False")
End If
End Sub
End Class
Public Class DAL
Private mcn As New SqlConnection
Public Sub OpenConnection()
mcn.ConnectionString = "Data Source=SQL;Initial Catalog=Northwind;User ID=sa"
mcn.Open()
End Sub
Public Sub CloseConnection()
mcn.Close()
End Sub
Public Function SelectOrderDetails() As DataSet
Dim sSQL As String
Dim da As New SqlDataAdapter
Dim cmd As New SqlCommand
Dim dtm As DataTableMapping = New DataTableMapping
Dim ds As New DataSet
Try
sSQL = "SELECT * FROM [Order Details]"
cmd.CommandText = sSQL
cmd.Connection = mcn
dtm.DataSetTable = "OrderDetails"
dtm.SourceTable = "Table"
da.TableMappings.Add(dtm)
da.SelectCommand = cmd
da.Fill(ds)
Catch ex As Exception
MessageBox.Show(ex.ToString)
End Try
Return ds
End Function
Public Function SelectProducts() As DataSet
Dim sSQL As String
Dim da As New SqlDataAdapter
Dim cmd As New SqlCommand
Dim dtm As DataTableMapping = New DataTableMapping
Dim ds As New DataSet
Try
sSQL = "SELECT * FROM Products"
cmd.CommandText = sSQL
cmd.Connection = mcn
dtm.DataSetTable = "Products"
dtm.SourceTable = "Table"
da.TableMappings.Add(dtm)
da.SelectCommand = cmd
da.Fill(ds)
Catch ex As Exception
MessageBox.Show(ex.ToString)
End Try
Return ds
End Function
End Class
</code>Sv: Problem med bundna comboboxar
/MickeSv: Problem med bundna comboboxar
Det borde du enkelt kunna lösa på följande vis (pseudokod):
<code>
Sub combobox1_ValueChanged() handles ...
MyValueChanged()
End Sub
Sub OnLoad() handles ...
combobox1.Value = 2
MyValueChanged()
End Sub
Sub MyValueChanged()
...
End Sub
</code>Sv: Problem med bundna comboboxar
Har formulerat om ursprungsfrågan samt skickat med exempelkod. Hoppas att det förklarar lite mer i detalj vilket problemet är.
mvh
MagnusSv: Problem med bundna comboboxar
Har testat med SelectedIndexChanged och det fungerar bättre. Dock tycker jag fortfarande att SelectedValueChanged är lite inkonsekvent men så länge man kan gå runt det så är det ok.
Tyvärr kvarstår grundproblemet. EndCurrentEdit tar bort mitt default-värde när jag trycker 'HasChanges?' och datasetet glömmer bort att jag verkligen satt ett värde i kod. Det ända sättet att få bindningen att uppdatera datasetet verkar vara att välja ett värde mha att klicka i combon. Några bra idéer på hur man kan gå runt detta?
mvh
Magnus