Is this a bug in combobox ????(revisited)

A

al

Hi,

I have a WinForm with a combobox bound to a dataset and the properties
of the comb are all set correctly. It works fine until I change the
first value in the list, then proplem starts. This first value becoms
the default in all next values as you navigate in dataset (with next
or prev. buttons).

Any idea as why combobox does this???

Private Sub Mian_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load

Try
cbo.DataSource = ds.Tables("employees")
cbo.DisplayMember = "FirstName"
cbo.ValueMember = "ReportsTo"

cboreportsto.DataBindings.Add("SelectedValue", ds,
"employees.ReportsTo")

Catch ex As SqlException
MsgBox(ex.Message)
End Try
End Sub

MTIA,
Grawsha
 
C

Cor

Hi Grawsa,

From your code I cannot see it, but why you use a Try block for something
that has no external influence and than while there is no sql statement in
it catch only the sqlException?

And I see (expect) you have 2 comboboxes cbo and cboreportsto?

Or is this something strange?

Cor
 
A

al

Hi,

I have a WinForm with a combobox bound to a dataset and the properties
of the comb are all set correctly. It works fine until I change the
first value in the list, then proplem starts. This first value becoms
the default in all next values as you navigate in dataset (with next
or prev. buttons).

Any idea as why combobox does this???

Private Sub Mian_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load

Try
cbo.DataSource = ds.Tables("employees")
cbo.DisplayMember = "FirstName"
cbo.ValueMember = "ReportsTo"

cboreportsto.DataBindings.Add("SelectedValue", ds,
"employees.ReportsTo")

Catch ex As SqlException
MsgBox(ex.Message)
End Try
End Sub

MTIA,
Grawsha

Thank you! Just fixed it. I had to chanage the SelectedVaule property
of combobox to Text and bind to not the ValueMember but the firstName.
Now, when I change the text in combbox to something else, it is not
reflected in the dataset????? While if I edited the text itself, it
is refledt in dataset.


Grawsha
 
K

Kathleen Dollard

Al,

Could you reread and restate this, unless someone else guesses at what you
are trying to say correctly?

Or if you really set the SelectedValue to Text, that probably cofnused
things. Maybe post your newValueMember/DisplayMember and binding.
 
A

al

Thank you! Just fixed it. I had to chanage the SelectedVaule property
of combobox to Text and bind to not the ValueMember but the firstName.
Now, when I change the text in combbox to something else, it is not
reflected in the dataset????? While if I edited the text itself, it
is refledt in dataset.


Grawsha

Cor,
Ok, that was part of a larger code (ignore it please). Cbo and
cboreprotsto are the same. I just wanted to abbrivate things and
forgot to do it all. As you might have noticed. I did solve the
problem of combobox change the SelectedValue to just one in all
records. But can you help me with this:
 
A

al

Kathleen Dollard said:
Al,

Could you reread and restate this, unless someone else guesses at what you
are trying to say correctly?

Or if you really set the SelectedValue to Text, that probably cofnused
things. Maybe post your newValueMember/DisplayMember and binding.


Sorry for the bad writing!

I have a form with a combobox (cbo) bound to a dataset (there are
other controls on the same form that are not relevant to this problem
and I deleted thier codes). I used combobox properties (DataMember,
DataSource and ValueMember) like this, among other things.

'string for connection

Dim str As String = "data source=pc1;initial
catalog=northwind;integrated security= true"

Dim cn As SqlConnection = New SqlConnection(str)

'this kind of sql sta. enables me to have first and last name col. as
one col.

Dim cmd As SqlCommand = New SqlCommand("SELECT
E1.EmployeeID,E1.Title," & _
"E2.FirstName + ' ' + E2.LastName AS ReportsToName,E1.FirstName," &
_
"E1.ReportsTo,E1.LastName FROM Northwind..Employees AS E1 LEFT OUTER
JOIN" & _
" Northwind..Employees AS E2 ON E2.EmployeeID =
E1.ReportsTo", cn)

Dim ds As New DataSet
Dim da As New SqlDataAdapter(cmd)

da.Fill(ds, "employees")

cbo.DataSource = ds.Tables("employees")
cbo.DisplayMember = "ReportsToName"
cbo.ValueMember = "ReportsTo"

cbo.DataBindings.Add("Text", ds,
"employees.ReportsToName")


This just works fine for me. I do update and delete with no problem.
However, when I move in the dataset with Next and Previous Buttons
then I change the value in the list of the combobox (by selecting
combobox dropdown list), it chnages OK and I can update the database,
but when I move back to that same value I have just changed, it shows
the old value before the upadte (while it should show the updated
value, as this is the benefit of databinding)

You may say change Text prty. to SelectedValue in the databindng of
cbo and datamember similar to the one in ValueMember, I did try that,
but then there was a proplem. CBO keeps the text in the first value
(first shown text) as the default for all subsequent values. This
happens when I change the value of cbo to other values in the
dropdown list. (I did NOT use selectedindex=-1 or 0, so the article
Q327244 does not apply to my case)

I hope this clears the conf.

MTIA,
Grawsha
 
S

Shisero Alala

I will presume that your main binding is on the Employees
table, and that the end-user will use the combobox to
select a new supervisor ("ReportsTo") for the current
employee record.

It seems your problem is binding BOTH the data and list
functionality of a combobox to the same employees
dataset/view.

Futhermore, you are binding to diferent binding contexts.

Try this: -

' Use a dataview to prevent the combobox
' list scrolling from interfering with
' main table navigation...
Dim dvwReportsTo As DataView = New DataView
(Me.ds.Tables("Employees"))

With cbo
' bind the data functionality to the table
.DataBindings.Add( _
New System.Windows.Forms.Binding( _
"SelectedValue", Me.ds.Tables
("Employees"), _
"ReportsTo"))

' separately, bind the list functionality to a
view
.DataSource = dvwReportsTo
.ValueMember = "EmployeeID"
.DisplayMember = "FirstName"
End With

Your errors: -

- u choose "ReportsTo" in both instances. This restricts
the selection to the table's currently selected
ReportsTos.

- your list data binding is at the table-level --
ds.Tables("Employees") -- which differs from your data
binding, which is at the dataset level --
ds, "Employees.ReportsTo".

Either be consistent with table-level binding in all
instances: -

DataSource = ds.Tables("Employees")
AND
(ds.Tables("Employees"), "ReportsTo")

OR with dataset level binding: -

DataSource = ds
DataMember = "Employees"
AND
(ds, ("Employees.ReportsTo"))

DON'T MIX as u have done!

When u get to currencymanagers (which you have, by the
way, even tho u don't know it), this becomes matter-of-
life-and-death important!!!

The following 2 cur mgrs are NOT equivalent...

Table-binding: -

curMgrEmployees1 = CType(Me.BindingContext
(Me.dstNothwind.Tables("Employees")), CurrencyManager)

Dataset-binding: -

curMgrEmployees2 = CType(Me.BindingContext
(Me.dstNothwind, "Employees"), CurrencyManager)

Regards,
Anthony
 
C

Cor

Hi Al,

I did try it and I do not understand it either,

In my opinion the combobox is the most buggiest control from Net
So you have always to test everything and it is unpredictable what it does
in different occasions, this one is new for me and did cost me a lot of
time.

I tried first as you do and could not get it working att all, the shortest I
could reach was when it changes the database with items from the next
selection

This kind of behaviour I have seen more with the combobox but that was when
there was no datatable binding and then it was the previous item (with
selection change commited not with index change).

You probably also have seen that bug about the first text entrance, I think
that has to do with this, it looks if the combobox update the changes to
late. (Not on the selection but at the first key enter in the box)

When I did this
Me.ComboBox1.DataBindings.Add(New Binding("Text", ds.Tables(0),
"FirstName"))
I got the behaviour I described above.

Then when I putted a textbox on the form and did this (and deleted the other
one)
Me.TextBox1.DataBindings.Add(New Binding("Text", ds.Tables(0), "FirstName"))
I did do the changes good in the dataset, but strangly enough on the second
change of the combobox selection. (I did use the selected change committed
to do the update proces)

I find it strange too.

But I hope it helps, because you are not the only one who does not
understand this?

Cor








al said:
(e-mail address removed) (al) wrote in message

Cor,
Ok, that was part of a larger code (ignore it please). Cbo and
cboreprotsto are the same. I just wanted to abbrivate things and
forgot to do it all. As you might have noticed. I did solve the
problem of combobox change the SelectedValue to just one in all
records. But can you help me with this:
it changes fine, but when I move next or prev. and comeback again, it still
holds the old value)?? While if I edited the text itself, it is reflected in
dataset.
 
C

Cor

Hi Al,

It does not change a thing, but when I added currencymanager.endcurrentedit
before the test if there where changes it works OK when I use the extra
textbox (Not your sitiuation).

But maybe I don't see it either, so i am also currious if someone has a
solution.

Cor
 
K

Kathleen Dollard

Grawsha,

I hate to start here, but be really careful with this approach. If you
concatonate in any text fields, you've got SQL injection Be sure to use
paramters.
This just works fine for me. I do update and delete with no problem.
However, when I move in the dataset with Next and Previous Buttons
then I change the value in the list of the combobox (by selecting
combobox dropdown list), it chnages OK and I can update the database,
but when I move back to that same value I have just changed, it shows
the old value before the upadte (while it should show the updated
value, as this is the benefit of databinding)

You do have to hold your mouth just write for combo boxes, but they do work.

First, binding your DataSource (for the dropdown) and the Data value (Text)
to the same source is probably your problem. You need to ensure these use
different currency managers. To test this hypothesis, create a DataView and
use it ast he DataSource. If you still get the same failure, you have
disproved that hypothesis and repost to rethink other options.

Yes, you may also need EndCurrentEdit. That's a separate issue.

A common source of problems with databinding. Remove temporarily any Format
or Parse events you have on this form at all.
 
C

Cor

Hi Kathleen,

I was busy with this so I did full intrest looking at your answer.
I have some questions about it because I could not resolve this problem and
being busy with it, I saw Grawsah was only telling things which I think he
had investigated good.

The questions:
I hate to start here, but be really careful with this approach. If you
concatonate in any text fields, you've got SQL injection Be sure to use
paramters.

I really do not understand what a dataset has to do with SQL more than that
SQL can be one of the suppliers of a dataset. A dataset is disconnected from
SQL when it is binded to a combox.
You do have to hold your mouth just write for combo boxes, but they do
work.

The combobox is the control with the most problems I have seen in the dotnet
newsgroups.
So maybe you first can try some things before you write this.
First, binding your DataSource (for the dropdown) and the Data value (Text)
to the same source is probably your problem. You need to ensure these use
different currency managers. To test this hypothesis, create a DataView and
use it ast he DataSource. If you still get the same failure, you have
disproved that hypothesis and repost to rethink other options.

A combobox is a combined control.
It has a textbox and a listdown. Grawsah is binding the text to his
datatable, what should he else have to bind.

The dataview is only an filter between the datatable and the listbox what
would that make a difference.

Nevertheless I tried all your sugestions.

And therefore I ask you please send us some code.
I could do it with the code Grawsah did suply so you can do it a lot better
I think?

I will be glad if I know what I did wrong,

Cor
 
S

Shisero Alala

I will presume that your main binding is on the Employees
table, and that the end-user will use the combobox to
select a new supervisor ("ReportsTo") for the current
employee record.

It seems your problem is binding BOTH the data and list
functionality of a combobox to the same employees
dataset/view.

Futhermore, you are binding to diferent binding contexts.

Try this: -

' Use a dataview to prevent the combobox
' list scrolling from interfering with
' main table navigation...
Dim dvwReportsTo As DataView = New DataView
(Me.ds.Tables("Employees"))

With cbo
' bind the data functionality to the table
.DataBindings.Add( _
New System.Windows.Forms.Binding( _
"SelectedValue", Me.ds.Tables
("Employees"), _
"ReportsTo"))

' separately, bind the list functionality to a
view
.DataSource = dvwReportsTo
.ValueMember = "EmployeeID"
.DisplayMember = "FirstName"
End With

Your errors: -

- u choose "ReportsTo" in both instances. This restricts
the selection to the table's currently selected
ReportsTos.

- your list data binding is at the table-level --
ds.Tables("Employees") -- which differs from your data
binding, which is at the dataset level --
ds, "Employees.ReportsTo".

Either be consistent with table-level binding in all
instances: -

DataSource = ds.Tables("Employees")
AND
(ds.Tables("Employees"), "ReportsTo")

OR with dataset level binding: -

DataSource = ds
DataMember = "Employees"
AND
(ds, ("Employees.ReportsTo"))

DON'T MIX as u have done!

When u get to currencymanagers (which you have, by the
way, even tho u don't know it), this becomes matter-of-
life-and-death important!!!

The following 2 cur mgrs are NOT equivalent...

Table-binding: -

curMgrEmployees1 = CType(Me.BindingContext
(Me.dstNothwind.Tables("Employees")), CurrencyManager)

Dataset-binding: -

curMgrEmployees2 = CType(Me.BindingContext
(Me.dstNothwind, "Employees"), CurrencyManager)

Regards,
Anthony
 
C

Cor

Hi Shisero,

Maybe you can find why this does not work.

The combobox is a combination from a listbox and a textbox, so I think this
should work in both situations the same.

I am very curious what it can be?

Cor

\\\
Private ds As New DataSet
Private cma As CurrencyManager
Private flag As Boolean = False
Private Sub Form1_Load(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
Dim Conn As New SqlConnection _
("Server=localhost;DataBase=northwind;Integrated Security=SSPI")
Try
Dim da As New SqlDataAdapter _
("Select EmployeeID, FirstName from Employees", Conn)
da.Fill(ds)
Catch ex As Exception
MessageBox.Show("there was something filling")
Me.Close()
Finally
Conn.Close()
End Try
Me.ComboBox1.BeginUpdate()
cma = CType(BindingContext(ds.Tables(0)), CurrencyManager)
Dim dv As New DataView(ds.Tables(0))
'-------------------------------------------------------------
'DOES NOT WORK
Me.ComboBox1.DataBindings.Add(New Binding("Text", dv, "FirstName"))
'THIS WORKS FINE
Me.TextBox1.DataBindings.Add(New Binding("Text", dv, "FirstName"))
'---------------------------------------------------------------
Me.ComboBox1.DataSource = dv
Me.ComboBox1.DisplayMember = "FirstName"
Me.ComboBox1.ValueMember = "FirstName"
Me.ComboBox1.EndUpdate()
flag = True
End Sub
Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged
If flag Then
cma.EndCurrentEdit()
If ds.HasChanges Then
Dim Conn As New SqlConnection _
("Server=localhost;DataBase=northwind;Integrated
Security=SSPI")
Try
Dim da As New SqlDataAdapter _
("Select EmployeeID, FirstName from Employees", Conn)
Dim cmb As New SqlCommandBuilder(da)
da.Update(ds.GetChanges)
ds.AcceptChanges()
Catch ex As Exception
MessageBox.Show("there was something updating")
Finally
Conn.Close()
End Try
Me.ComboBox1.Refresh()
End If
End If
End Sub
///
 
S

Shisero Alala

You're almost there...

STEP 1:
FOR THE DATA BINDING, YOU BOUND THE COMBOBOX'S TEXT FIELD
(wrong) TO THE DATAVIEW (wrong): _
' DOES NOT WORK
Me.ComboBox1.DataBindings.Add(New Binding
("Text", dv, "FirstName"))

Instead, bind the combobox's SELECTEDVALUE field to the
DATASET's Table, as follows: _

ComboBox1.DataBindings.Add(New Binding("SelectedValue", _
ds.Tables("Employees"), "EmployeeID"))

In other words,

1. Datasource: bind to the dataset.table and not the
dataview
2. Control's property: bind the cbo's "SelectedValue" and
NOT "Text"

Got that?

*****************************************************

STEP 2:
The valuemember should be EmployeeID, not Firstname as
you declared: -

ComboBox1.DataSource = dv
ComboBox1.ValueMember = "EmployeeID" ' this line was
wrong
ComboBox1.DisplayMember = "FirstName"


That should work...
 
S

Shisero Alala

Cor,

Make these changes ...
1.
cma = CType(BindingContext(ds.Tables
(Employees)), CurrencyManager)

2.
Dim dv As New DataView(ds.Tables("Employees"))

3. Bind the selectedvalue to dataset.tables + employee id

ComboBox1.DataBindings.Add(New Binding("SelectedValue",
ds.Tables("Employees"), "EmployeeID"))

4. List functionality to view

ComboBox1.DataSource = dv
ComboBox1.DisplayMember = "FirstName"
ComboBox1.ValueMember = "EmployeeID" ' CHECK THIS CHANGE
 
C

Cor

Hi Shisero,

I did it already when you did send the message, and I did it over again
before I wrote this message to be sure, but it still gives loops.

(To be true I had this already done while testing, but I was also helping
someone, it is not my problem)

To do something on your comments to help back. Because I appriciate it of
course what you are doing.

cma = CType(BindingContext(ds.Tables ("Employees")), CurrencyManager)
cma=CType(BindingContext(ds.Tables(0),CurrencyManager)

This is an equivalent if there is only one table.

But thanks

Cor
 
S

scorpion53061

Cor,

Please post the orininal message in this thread. I think I want to save
your answer.
 
C

Cor

Hi Scorpion,

It was already in, but it was only for testing.
\\\
Imports System.Data.SqlClient
Public Class Form1
Inherits System.Windows.Forms.Form
Private ds As New DataSet
Private cma As CurrencyManager
Private flag As Boolean = False
Private Sub Form1_Load(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
Dim Conn As New SqlConnection _
("Server=localhost;DataBase=northwind;Integrated Security=SSPI")
Try
Dim da As New SqlDataAdapter _
("Select EmployeeID, FirstName from Employees", Conn)
da.Fill(ds)
Catch ex As Exception
MessageBox.Show("there was something filling")
Me.Close()
Finally
Conn.Close()
End Try
Me.ComboBox1.BeginUpdate()
cma = CType(BindingContext(ds.Tables(0)), CurrencyManager)
Dim dv As New DataView(ds.Tables(0))
'-------------------------------------------------------------
'DOES NOT WORK
' Me.ComboBox1.DataBindings.Add(New Binding("Text", dv,
"FirstName"))
'THIS WORKS FINE
Me.TextBox1.DataBindings.Add(New Binding("Text", dv, "FirstName"))
'---------------------------------------------------------------
Me.ComboBox1.DataSource = dv
Me.ComboBox1.DisplayMember = "FirstName"
Me.ComboBox1.ValueMember = "FirstName"
Me.ComboBox1.EndUpdate()
flag = True
End Sub
Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged
If flag Then
cma.EndCurrentEdit()
If ds.HasChanges Then
Dim Conn As New SqlConnection _
("Server=localhost;DataBase=northwind;Integrated
Security=SSPI")
Try
Dim da As New SqlDataAdapter _
("Select EmployeeID, FirstName from Employees", Conn)
Dim cmb As New SqlCommandBuilder(da)
da.Update(ds.GetChanges)
ds.AcceptChanges()
Catch ex As Exception
MessageBox.Show("there was something updating")
Finally
Conn.Close()
End Try
Me.ComboBox1.Refresh()
End If
End If
End Sub
End Class
///
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top