Perplexed...so very Perplexed

  • Thread starter Thread starter Jim Heavey
  • Start date Start date
J

Jim Heavey

Hello
My problem is the items that I am building do not show up in the ListView
control.

My problem arrose when I attempted to create a generic set of routines which
would build the list view Items for any Listview. After writing the generic
routine, nothing ever shows up in the ListView Control, even though if I
Console.WriteLine the items in the control , each of the items shows up just
fine. I have looked at this thing all day long and I can not explain why they
are not showing up.

Can someone spot something stupid I am doing wrong? I believe I have included
all the code needed, all that needs to be done it to add the listView Control
to the form and past this code into the form Load event (commenting out the
code which builds the ListView items directly rather then calling the generic
routine - RebuildListView) .

Here is the code to set up the ListView Control:

ListView1.View = View.Details
ListView1.LabelEdit = False
ListView1.AllowColumnReorder = False
ListView1.CheckBoxes = False
ListView1.FullRowSelect = True
ListView1.GridLines = True
ListView1.Sorting = SortOrder.Ascending
ListView1.Columns.Add("Stuff", 60, HorizontalAlignment.Left)
ListView1.Columns.Add("Stuff2", 60, HorizontalAlignment.Left)

Here is the code to build a table which will contain the values that I will
eventually place into the listView:
Dim tbl As New DataTable("Temp")
tbl.Columns.Add("Stuff1", GetType(String))
tbl.Columns.Add("Stuff2", GetType(String))
Dim dvTemp As New DataView(tbl)
Console.WriteLine("Total records currently in Temp Table = {0}", dvTemp.Count)
Dim row As DataRow = tbl.NewRow
row.Item(0) = "aaaa"
row.Item(1) = "bbbb"
tbl.Rows.Add(row)

Here is the code to add the items directly ( Before I attempted to generitize)

Dim it As String = dvTemp(0).Item(0)
Dim lsvItem2 As New ListViewItem(CStr(dvTemp(0).Item(0)))
lsvItem2.SubItems.Add(dvTemp(0).Item(1))
ListView1.Items.Add(lsvItem2)

Now Here are the subs/functions that I wrote to make the process generic:

Dim cols() As Integer = {0, 1} 'Identifies the Columns in the DataView to
Place in the
ListView
Call RebuildListView(ListView1, dvTemp, False, cols, -1, "")

Explanation: Listview = The control to act upon
DvTemp = View which contains the data to use to build the
ListView Items
False = Boolean to identify if the checkbox feature of the
ListView is used, in this
case, we are not using it.
Cols = This is an array of Integers which contain the
column number
which you are interested in placing in the
ListView - assumption is that
you will not always want to list every column in
the dataview.
The next 2 columns are used to identify a row in the ListView
that you want to
ultimately identify as a "selected" item in the ListView
control - In this situation we
are not using this feature, so we are setting those to dummy
values
-1 = If you want to identify a specify a specific column
to match on
"" = The data you want to match on

Now here is the RebuildListView Function

Private Function RebuildListView(ByVal lstView As ListView, ByVal dv As
DataView, _
ByVal chkBox As Boolean, ByVal columns() As Integer, _
ByVal matchCol As Integer, ByVal matchString As String) As Integer

'*********************
'* The purpose of the procedure is to provide a generic ability to
'* rebuild all the list items in a ListView based upon the parameters
'* passed. The columns array identifies the column numbers to use to
'* build the listview items. The checkBox value passed identifies if
'* the listview uses the checkbox feature - if it does, then a "" loaded as
'* its' value in the constructor and the first column must contain the
'* boolean to set the appropriate value of the Checkbox. The remaining
'* columns are place into sub-items in the listview in the order specified
'*********************
Dim row As DataRowView
Dim values(columns.Length - 1) As Object
Dim i As Integer
Dim rowThatMatched As Integer = -1 'Index of row matching criteria provided
lstView.Clear()
Dim rowCnt As Integer = 0
For Each row In dv
Dim indx As Integer
i = 0
rowCnt += 1
Console.WriteLine("RebuildListView Record #{0} for listview: {1}", rowCnt,
lstView.Name)
For Each indx In columns 'columns numbers passed as parameter
values(i) = row.Item(columns(i)) 'get the column value requested
Console.WriteLine("Place the following in the table {0}", values(i))
If columns(i) = matchCol Then
If matchString = row.Item(columns(i)) Then
rowThatMatched = i
End If
End If
i += 1
Next
Console.WriteLine()
AddListItem(chkBox, values, lstView)
Next
Return rowThatMatched

End Function

The subroutine which actually builds the ListView Items

Private Sub AddListItem(ByVal checkOpt As Boolean, ByVal values() As Object,
ByVal lstview As ListView)

Dim li As ListViewItem
If checkOpt = True Then 'using the checkbox feature of ListView?
li = New ListViewItem("")
Console.WriteLine("boolean value = {0}", CStr(values(0)))
li.Checked = CBool(values(0))
Else
li = New ListViewItem(CStr(values(0)))
End If
Dim i As Integer = 1 'already loaded the first value, so start at the second
While i < values.Length 'loop thru the remaining items in the array and add to
the Subitems
li.SubItems.Add(values(i))
Console.WriteLine("Adding the following value to the Listview: {0}",
values(i))
i += 1
End While
lstview.Items.Add(li)

End Sub
 
Hi Jim,

It makes a nice change when someone gives a clear account of their
problem. Its great when someone prepares a working test case which doesn't
include reams of extraneous <*&*&>. Its refreshing when the code that's given
doesn't produce loads of errors, demand added references, called non-existant
objects, methods, what have you.

Yours is one of those rare requests and I thank you. :-)

I have one small request, myself. One that will take you up to the
"perfect customer" level. :-D

Could I have a zip of the code rather than having it inline? The layout is
lost and long lines are wrapped. I <am> already working on it so I might have
finished before you respond, but if not, it would be useful.

Regards,
Fergus
 
Well, you know I knew it would be the simplest thing...

But I guess I do not understand why this is a problem. I thought
ListView1.Clear() method would clear out any prior entries which existed and
then allow me to insert new ones. Where I have the ListView1.Clear() is the
perfect place for clearing any of the "old" values out and loading up the new
stuff. I must be missing something still.

It was a great Relief to actually seem them show up after all the looking that
I did.

Lastly, I did not understand this comment " ps. When testing, use Dim cols()
As Integer = {2, 1, 0} as this will ensure that you get your columns right
too." Why are you passing 3 column numbers? It probably that I am so tired
of looking at this and it will make sense to me in the morning....

Toodle!!!!!!!!!
 
Hi Jim,

|| Well, you know I knew it would be the simplest thing.

How often it <is>!! :-)

ListView.ColumnHeaderCollection.Clear clears the column headings.
ListView.ListViewItemCollection.Clear clears the values.
ListView.Clear clears both.

I added a third column when I was testing. What I was indicating was that
the columns should be reversed so that you'd notice how well (or not) your
routine obtained the correct values according to the Cols array, but would
show you that the column headings <hadn't> been reordered.

General principle: If ever you're working with arrays of indexes, like
Cols(), it's always a good idea to <avoid> having Col(0) = 0, Col(1) = 1, etc
because, for instance, there's no difference between X = SomeValue(I) and X =
SomeValue(Col(I)). If you mix 'em up errors should be more noticable.

Best wishes,
Fergus
 
Back
Top