populate 1 listbox with another listbox and vice versa

D

Dave

Hi All,

I have a windows form that contains 2 listboxes and 2 buttons.
The listbox on the right is populated by a database routine (This is the
easy part).
The listbox on the left is populated by 1 or more selected items from the
listbox on the right after clicking an Add button.
Clicking a "Remove" button will remove the item from the left listbox and
restore it back to the right box.

I have some code that uses 3 datasets:

1 for the data from the DB for the initial populating of the right hand side
listbox called "dsRegionNamesDB" .
1 for the data that changes in the righthand listbox (lstRegionNames) called
"dsRegionNames"
1 for the data that changes in the lefthand listbox
(lstRegionNamesSelected)call "dsSelectedRegionNames"

Table(0) is used in all datasets (though probably should do this with 3
tables inside 1 dataset, but I'm still a beginner to all this VB.Net stuff
and OOP in general).

The 2 listboxes are bound to the corresponding datatables in their
respective datasets so that changes to the datatables are
immediately reflected in the listboxes.

While I can't seem to get this to work right, I do know that it is possibly
the slowest implementation of what should be very fast.

Here is the (non-working) code - (I can't get the left hand listbox to
display the actual values)

Private dsRegionNames As New DataSet

Private dsSelectedRegionNames As New DataSet

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

Rebuild()

loadDBRegionNames()

End Sub

Private Sub loadDBRegionNames()

Dim dsDBRegionNames As DataSet

dsDBRegionNames = SalesRegionsDB.GetRegionNamesActive

lstRegionNames.DataSource = dsDBRegionNames.Tables(0)

lstRegionNames.DisplayMember = "reg_name"

lstRegionNames.ValueMember = "reg_idx"

dsRegionNames = dsDBRegionNames

End Sub

Private Sub Add()

Dim oRow As DataRow

If lstRegionNames.SelectedIndex >= 0 Then

oRow = dsSelectedRegionNames.Tables(0).NewRow

oRow("reg_name") = CType(lstRegionNames.SelectedItem,
DataRowView).Row("reg_name")

oRow("reg_idx") = CType(lstRegionNames.SelectedItem,
DataRowView).Row("reg_idx")

dsSelectedRegionNames.Tables(0).Rows.Add(oRow)

dsRegionNames.Tables(0).Rows.RemoveAt(lstRegionNames.SelectedIndex)

End If

End Sub





Private Sub Remove()

Dim oRow As DataRow

If lstSelectedRegionNames.SelectedIndex >= 0 Then

oRow = dsRegionNames.Tables(0).NewRow

oRow("reg_name") = CType(lstSelectedRegionNames.SelectedItem,
DataRowView).Row("reg_name")

oRow("reg_idx") = CType(lstSelectedRegionNames.SelectedItem,
DataRowView).Row("reg_idx")

dsRegionNames.Tables(0).Rows.Add(oRow)

dsSelectedRegionNames.Tables(0).Rows.RemoveAt(lstSelectedRegionNames.Selecte
dIndex)

End If

End Sub

Private Sub Rebuild()

dsRegionNames = New DataSet

dsRegionNames.Tables.Add(New DataTable)

dsRegionNames.Tables(0).Columns.Add("reg_name")

dsRegionNames.Tables(0).Columns.Add("reg_idx")

dsSelectedRegionNames.Tables.Add(New DataTable)

dsSelectedRegionNames.Tables(0).Columns.Add("reg_name")

dsSelectedRegionNames.Tables(0).Columns.Add("reg_idx")

lstRegionNames.DataSource = dsRegionNames.Tables(0)

lstSelectedRegionNames.DataSource = dsSelectedRegionNames.Tables(0)

End Sub

Private Sub btnAdd_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnAdd.Click

Me.Add()

End Sub

Private Sub btnRemove_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnRemove.Click

Me.Remove()

End Sub





Anywho, when the Add button is pressed the value "System.Data.DataRowView"
is what appears in the left hand side instead of the actual value.
Everything else seems to be working (albeit it takes 5 seconds for the first
value to move over).

First: Why do the values not show? - it seems like it should and I've
verified the data is actually getting to the initial dataset table(0).
Second: Is there a faster way of doing this?

TIA

MC
 
C

Cor Ligthert

Dave,

When I saw your problem I had to think on this solution, I wrote it first in
text however thought let me try it first. It works, however it has a side
effect. The first selection is slow. So when somebody read this, can he try
it. Because probably I can look a whole day to it and than oversee
something. After the first everything behaves at normal speed.

\\\
Private Sub Form1_Load _
(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles MyBase.Load
Dim ds As New DataSet
CreateDs(ds)
Dim dc As New DataColumn("mychecker", GetType(System.Boolean))
dc.DefaultValue = True
ds.Tables(0).Columns.Add(dc)
ds.Tables(0).Columns("mychecker").DefaultValue = True
Dim dv1 As New DataView(ds.Tables(0))
Dim dv2 As New DataView(ds.Tables(0))
dv1.RowFilter = "mychecker = true"
dv2.RowFilter = "mychecker = false"
ListBox1.DataSource = dv1
ListBox1.DisplayMember = "Name"
ListBox2.DataSource = dv2
ListBox2.DisplayMember = "Name"
AddHandler ListBox1.SelectedIndexChanged, _
AddressOf ListBox1_SelectedIndexChanged
AddHandler ListBox2.SelectedIndexChanged, _
AddressOf ListBox2_SelectedIndexChanged
End Sub

Private Sub ListBox1_SelectedIndexChanged _
(ByVal sender As System.Object, ByVal e As System.EventArgs)
RemoveHandler ListBox1.SelectedIndexChanged, _
AddressOf ListBox1_SelectedIndexChanged
RemoveHandler ListBox2.SelectedIndexChanged, _
AddressOf ListBox2_SelectedIndexChanged
If ListBox1.SelectedIndices.Count > 0 Then
Dim dv As DataView = DirectCast(ListBox1.DataSource, DataView)
dv(ListBox1.SelectedIndex)("mychecker") = False
ListBox1.SelectedIndex = -1
ListBox2.SelectedIndex = -1
End If
AddHandler ListBox1.SelectedIndexChanged, _
AddressOf ListBox1_SelectedIndexChanged
AddHandler ListBox2.SelectedIndexChanged, _
AddressOf ListBox2_SelectedIndexChanged
End Sub

Private Sub ListBox2_SelectedIndexChanged _
(ByVal sender As System.Object, ByVal e As System.EventArgs)
RemoveHandler ListBox1.SelectedIndexChanged, _
AddressOf ListBox1_SelectedIndexChanged
RemoveHandler ListBox2.SelectedIndexChanged, _
AddressOf ListBox2_SelectedIndexChanged
If ListBox2.SelectedIndices.Count > 0 Then
Dim dv As DataView = DirectCast(ListBox2.DataSource, DataView)
dv(ListBox2.SelectedIndex)("mychecker") = True
ListBox1.SelectedIndex = -1
ListBox2.SelectedIndex = -1
End If
AddHandler ListBox1.SelectedIndexChanged, _
AddressOf ListBox1_SelectedIndexChanged
AddHandler ListBox2.SelectedIndexChanged, _
AddressOf ListBox2_SelectedIndexChanged
End Sub
///

Cor
 
D

Dave

Thanks Cor,

I'll have to study this to see if I can get it to work for me.
I think to speed these up would be to maybe use an arraylist or something
similar with less overhead than a dataset.
 
C

Cor Ligthert

Dave,

Why are you writting "with less overhead than a dataset", where you get that
crazy idea that an arraylist has lest overhead?

Because of all things you need to make yourself when using an arraylist for
this kind of purposes you will have probably a lot of extra overhead.

Have you any authorisezed documentation about that.

Cor
 
D

Dave

I've just read that from places on the Internet. What I heard is that an
array has the least overhead of all list objects, followed by queue, then
arraylist, then ListDictionary, HashTable, HybridDictionary and SortedList
(I may have the order wrong - pulling this from my memory), then datatables,
then datasets. The arraylist is one I like because you can add and remove
ranges of values without any looping. I assume the DataSet object has to
run additional code internally to handle multiple tables which would require
more memory and time, whereas an arraylist would not need the extra
preparatory steps and space.
Whatever the case, I went ahead and re-wrote this with 1 dataset and 2
datatables (below). (I'll try this with other list objects to see which is
most efficient)

Private dsDBRegionNames As New DataSet

Private dtRegionNames As New DataTable

Private dtSelectedRegionNames As New DataTable

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

Rebuild()

loadDBRegionNames()

End Sub

Private Sub loadDBRegionNames()

dsDBRegionNames = SalesRegionsDB.GetRegionNamesActive

lstRegionNames.DataSource = dsDBRegionNames.Tables(0)

lstRegionNames.DisplayMember = "reg_name"

lstRegionNames.ValueMember = "reg_idx"

dtRegionNames = dsDBRegionNames.Tables(0)

lstSelectedRegionNames.DisplayMember = "reg_name"

lstSelectedRegionNames.ValueMember = "reg_idx"

End Sub

Private Sub Add()

If lstRegionNames.SelectedIndex < 0 Then Return

Dim oRow As DataRow

oRow = dtSelectedRegionNames.NewRow

oRow("reg_name") = CType(lstRegionNames.SelectedItem,
DataRowView).Row("reg_name")

oRow("reg_idx") = CType(lstRegionNames.SelectedItem,
DataRowView).Row("reg_idx")

dtSelectedRegionNames.Rows.Add(oRow)

dtRegionNames.Rows.RemoveAt(lstRegionNames.SelectedIndex)

End Sub

Private Sub AddAll()

Dim oItem As DataRowView

Dim oRow As DataRow

For Each oItem In lstRegionNames.Items

oRow = dtSelectedRegionNames.NewRow

oRow("reg_name") = CType(oItem, DataRowView).Row("reg_name")

oRow("reg_idx") = CType(oItem, DataRowView).Row("reg_idx")

dtSelectedRegionNames.Rows.Add(oRow)

Next

dtRegionNames.Clear()

End Sub

Private Sub Remove()

If lstSelectedRegionNames.SelectedIndex < 0 Then Return

Dim oRow As DataRow

oRow = dtRegionNames.NewRow

oRow("reg_name") = CType(lstSelectedRegionNames.SelectedItem,
DataRowView).Row("reg_name")

oRow("reg_idx") = CType(lstSelectedRegionNames.SelectedItem,
DataRowView).Row("reg_idx")

dtRegionNames.Rows.Add(oRow)

dtSelectedRegionNames.Rows.RemoveAt(lstSelectedRegionNames.SelectedIndex)

End Sub

Private Sub RemoveAll()

Dim oItem As DataRowView

Dim oRow As DataRow

For Each oItem In lstSelectedRegionNames.Items

oRow = dtRegionNames.NewRow

oRow("reg_name") = CType(oItem, DataRowView).Row("reg_name")

oRow("reg_idx") = CType(oItem, DataRowView).Row("reg_idx")

dtRegionNames.Rows.Add(oRow)

Next

dtSelectedRegionNames.Clear()

End Sub

Private Sub Rebuild()

dtRegionNames = New DataTable

dtRegionNames.Columns.Add("reg_name")

dtRegionNames.Columns.Add("reg_idx")

dtSelectedRegionNames.Columns.Add("reg_name")

dtSelectedRegionNames.Columns.Add("reg_idx")

lstRegionNames.DataSource = dtRegionNames

lstSelectedRegionNames.DataSource = dtSelectedRegionNames

End Sub

Private Sub btnAdd_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnAdd.Click

Me.Add()

End Sub

Private Sub btnRemove_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnRemove.Click

Me.Remove()

End Sub

Private Sub btnAddAll_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnAddAll.Click

AddAll()

End Sub

Private Sub btnRemoveAll_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnRemoveAll.Click

RemoveAll()

End Sub
 
D

Dave

Here's an example showing some speed differences while reading data via
DataReader, Typed/UnTyped/Wrapped Datasets and Hashtables.
The hashtable is the overall winner in performance in this scenario (but the
most difficult to manage - the tradeoff). While this is not exactly what I'm
doing, it does clearly show the effects of the overhead of DataSets
w/regards to performance.
http://www.informit.com/articles/article.asp?p=31457&seqNum=7
 

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