Link to home
Start Free TrialLog in
Avatar of jxharding
jxharding

asked on

listview fill gives blank values, once column clicked and ">" is in columnheader,(descending order), only last row is filled, possible index problem

hi, i have a list view which is filled in this style:

                    ListView1.Items.Add(myreader("A").ToString())
                    ListView1.Items(i).SubItems.Add(B)
                    ListView1.Items(i).SubItems.Add(MyOleDBReader("C").ToString())

and i fill the listview via a datareader no problem
i used the following sub which i  got from e-e, and it sorts a listview by column and also the first time you click on the column,
the column's name gets a ">" in front of it , the second time you click on it it gets a "<" in front of it.
now the problem i have is that once i click on a columnheader and i refill the listview, all the items in the first   rows are
blank and only the last listviewitem is displayed correctly.
but if i click on it again, i can do a fill with no errors , and no blank spaces

i have tried all the columnclick subs i could find on the internet , and this one is the only one which i can actually get this far.
its as if the index is changed around.

I DO SET : LISTVIEW.SORTING = SORTORDER.NONE
, i also tried without it


this is the sub i use:

------------------------------------------------------
 Private m_SortingColumn As ColumnHeader

    ' Sort using the clicked column.
    Private Sub LISTVIEW1_ColumnClick(ByVal sender As _
        System.Object, ByVal e As _
        System.Windows.Forms.ColumnClickEventArgs) Handles _
        ListView1.ColumnClick
        ' Get the new sorting column.
        Dim new_sorting_column As ColumnHeader = _
            ListView1.Columns(e.Column)

        ' Figure out the new sorting order.
        Dim sort_order As System.Windows.Forms.SortOrder
        If m_SortingColumn Is Nothing Then
            ' New column. Sort ascending.
            sort_order = SortOrder.Ascending
        Else
            ' See if this is the same column.
            If new_sorting_column.Equals(m_SortingColumn) Then
                ' Same column. Switch the sort order.
                If m_SortingColumn.Text.StartsWith("> ") Then
                    sort_order = SortOrder.Descending
                Else
                    sort_order = SortOrder.Ascending
                End If
            Else
                ' New column. Sort ascending.
                sort_order = SortOrder.Ascending
            End If

            ' Remove the old sort indicator.
            m_SortingColumn.Text = _
                m_SortingColumn.Text.Substring(2)
        End If

        ' Display the new sort order.
        m_SortingColumn = new_sorting_column
        If sort_order = SortOrder.Ascending Then
            m_SortingColumn.Text = "> " & m_SortingColumn.Text
        Else
            m_SortingColumn.Text = "< " & m_SortingColumn.Text
        End If

        ' Create a comparer.
        ListView1.ListViewItemSorter = New _
            ListViewComparer(e.Column, sort_order)

        ' Sort.
        ListView1.Sort()
    End Sub
------------------------------------------------------

has someone had experience with this before?
im busy compiling a   sample project
i've been on this for at least a good few hours!
 thanks!

Avatar of jxharding
jxharding

ASKER

Public Class Form2
    Inherits System.Windows.Forms.Form

#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 GroupBox1 As System.Windows.Forms.GroupBox
    Friend WithEvents btnRefill As System.Windows.Forms.Button
    Friend WithEvents lvwBooks As System.Windows.Forms.ListView
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        Me.GroupBox1 = New System.Windows.Forms.GroupBox
        Me.btnRefill = New System.Windows.Forms.Button
        Me.lvwBooks = New System.Windows.Forms.ListView
        Me.GroupBox1.SuspendLayout()
        Me.SuspendLayout()
        '
        'GroupBox1
        '
        Me.GroupBox1.Controls.Add(Me.btnRefill)
        Me.GroupBox1.Dock = System.Windows.Forms.DockStyle.Top
        Me.GroupBox1.Location = New System.Drawing.Point(0, 0)
        Me.GroupBox1.Name = "GroupBox1"
        Me.GroupBox1.Size = New System.Drawing.Size(292, 100)
        Me.GroupBox1.TabIndex = 0
        Me.GroupBox1.TabStop = False
        Me.GroupBox1.Text = "GroupBox1"
        '
        'btnRefill
        '
        Me.btnRefill.Location = New System.Drawing.Point(40, 32)
        Me.btnRefill.Name = "btnRefill"
        Me.btnRefill.TabIndex = 0
        Me.btnRefill.Text = "Refill"
        '
        'lvwBooks
        '
        Me.lvwBooks.Dock = System.Windows.Forms.DockStyle.Fill
        Me.lvwBooks.Location = New System.Drawing.Point(0, 100)
        Me.lvwBooks.Name = "lvwBooks"
        Me.lvwBooks.Size = New System.Drawing.Size(292, 173)
        Me.lvwBooks.TabIndex = 1
        '
        'Form2
        '
        Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
        Me.ClientSize = New System.Drawing.Size(292, 273)
        Me.Controls.Add(Me.lvwBooks)
        Me.Controls.Add(Me.GroupBox1)
        Me.Name = "Form2"
        Me.Text = "Form2"
        Me.GroupBox1.ResumeLayout(False)
        Me.ResumeLayout(False)

    End Sub

#End Region

    ' The column currently used for sorting.
    Private m_SortingColumn As ColumnHeader

    ' Sort using the clicked column.
    Private Sub lvwBooks_ColumnClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.ColumnClickEventArgs) Handles lvwBooks.ColumnClick
        ' Get the new sorting column.
        Dim new_sorting_column As ColumnHeader = _
            lvwBooks.Columns(e.Column)

        ' Figure out the new sorting order.
        Dim sort_order As System.Windows.Forms.SortOrder
        If m_SortingColumn Is Nothing Then
            ' New column. Sort ascending.
            sort_order = SortOrder.Ascending
        Else
            ' See if this is the same column.
            If new_sorting_column.Equals(m_SortingColumn) Then
                ' Same column. Switch the sort order.
                If m_SortingColumn.Text.StartsWith("> ") Then
                    sort_order = SortOrder.Descending
                Else
                    sort_order = SortOrder.Ascending
                End If
            Else
                ' New column. Sort ascending.
                sort_order = SortOrder.Ascending
            End If

            ' Remove the old sort indicator.
            m_SortingColumn.Text = m_SortingColumn.Text.Substring(2)
        End If

        ' Display the new sort order.
        m_SortingColumn = new_sorting_column
        If sort_order = SortOrder.Ascending Then
            m_SortingColumn.Text = "> " & m_SortingColumn.Text
        Else
            m_SortingColumn.Text = "< " & m_SortingColumn.Text
        End If

        ' Create a comparer.
        lvwBooks.ListViewItemSorter = New ListViewComparer(e.Column, sort_order)

        ' Sort.
        lvwBooks.Sort()
    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        ' Remove any existing items.


        lvwBooks.Items.Clear()
        lvwBooks.View = View.Details
        lvwBooks.Sorting = SortOrder.None

        lvwBooks.Columns.Add("Name", 84, HorizontalAlignment.Left)
        lvwBooks.Columns.Add("Site", 84, HorizontalAlignment.Left)
        lvwBooks.Columns.Add("ISBN", 84, HorizontalAlignment.Left)

        ' Add data rows.

        Dim i As Integer
        For i = 0 To 3
            lvwBooks.Items.Add("Ready-to-Run Visual Basic Algorithms" & i & "")
            lvwBooks.Items(i).SubItems.Add("http://www.vb-helper.com/vba.htm" & i & "")
            lvwBooks.Items(i).SubItems.Add("0-471-24268-3" & i & "")
        Next i

        ' Size the columns.


        '' Size the columns.
        For j As Integer = 0 To lvwBooks.Columns.Count - 1
            lvwBooks.Columns(j).Width = -2
        Next j



    End Sub

    ' Make a ListView row.
    Private Sub ListViewMakeRow(ByVal lvw As ListView, ByVal item_title As String, ByVal ParamArray subitem_titles() As String)
        ' Make the item.
        Dim new_item As ListViewItem = lvw.Items.Add(item_title)

        ' Make the sub-items.
        For i As Integer = subitem_titles.GetLowerBound(0) To subitem_titles.GetUpperBound(0)
            new_item.SubItems.Add(subitem_titles(i))
        Next i
    End Sub


    Private Sub Reload_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnRefill.Click
        ' Remove any existing items.
        lvwBooks.Items.Clear()

        ' Add data rows.
        lvwBooks.Sorting = SortOrder.None

        Dim i As Integer
        For i = 0 To 3
            lvwBooks.Items.Add("Ready-to-Run Visual Basic Algorithms" & i & "")
            lvwBooks.Items(i).SubItems.Add("http://www.vb-helper.com/vba.htm" & i & "")
            lvwBooks.Items(i).SubItems.Add("0-471-24268-3" & i & "")
        Next i



    End Sub

End Class
Class ListViewComparer
    Implements IComparer

    Private m_ColumnNumber As Integer
    Private m_SortOrder As SortOrder

    Public Sub New(ByVal column_number As Integer, ByVal _
        sort_order As SortOrder)
        m_ColumnNumber = column_number
        m_SortOrder = sort_order
    End Sub

    ' Compare the items in the appropriate column
    ' for objects x and y.
    Public Function Compare(ByVal x As Object, ByVal y As _
        Object) As Integer Implements _
        System.Collections.IComparer.Compare
        Dim item_x As ListViewItem = DirectCast(x, _
            ListViewItem)
        Dim item_y As ListViewItem = DirectCast(y, _
            ListViewItem)

        ' Get the sub-item values.
        Dim string_x As String
        If item_x.SubItems.Count <= m_ColumnNumber Then
            string_x = ""
        Else
            string_x = item_x.SubItems(m_ColumnNumber).Text
        End If

        Dim string_y As String
        If item_y.SubItems.Count <= m_ColumnNumber Then
            string_y = ""
        Else
            string_y = item_y.SubItems(m_ColumnNumber).Text
        End If

        ' Compare them.
        If m_SortOrder = SortOrder.Ascending Then
            Return String.Compare(string_x, string_y)
        Else
            Return String.Compare(string_y, string_x)
        End If
    End Function

End Class

check this code



Public Class Form2
    Inherits System.Windows.Forms.Form

#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 GroupBox1 As System.Windows.Forms.GroupBox
    Friend WithEvents btnRefill As System.Windows.Forms.Button
    Friend WithEvents lvwBooks As System.Windows.Forms.ListView
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        Me.GroupBox1 = New System.Windows.Forms.GroupBox
        Me.btnRefill = New System.Windows.Forms.Button
        Me.lvwBooks = New System.Windows.Forms.ListView
        Me.GroupBox1.SuspendLayout()
        Me.SuspendLayout()
        '
        'GroupBox1
        '
        Me.GroupBox1.Controls.Add(Me.btnRefill)
        Me.GroupBox1.Dock = System.Windows.Forms.DockStyle.Top
        Me.GroupBox1.Location = New System.Drawing.Point(0, 0)
        Me.GroupBox1.Name = "GroupBox1"
        Me.GroupBox1.Size = New System.Drawing.Size(292, 100)
        Me.GroupBox1.TabIndex = 0
        Me.GroupBox1.TabStop = False
        Me.GroupBox1.Text = "GroupBox1"
        '
        'btnRefill
        '
        Me.btnRefill.Location = New System.Drawing.Point(40, 32)
        Me.btnRefill.Name = "btnRefill"
        Me.btnRefill.TabIndex = 0
        Me.btnRefill.Text = "Refill"
        '
        'lvwBooks
        '
        Me.lvwBooks.Dock = System.Windows.Forms.DockStyle.Fill
        Me.lvwBooks.Location = New System.Drawing.Point(0, 100)
        Me.lvwBooks.Name = "lvwBooks"
        Me.lvwBooks.Size = New System.Drawing.Size(292, 173)
        Me.lvwBooks.TabIndex = 1
        '
        'Form2
        '
        Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
        Me.ClientSize = New System.Drawing.Size(292, 273)
        Me.Controls.Add(Me.lvwBooks)
        Me.Controls.Add(Me.GroupBox1)
        Me.Name = "Form2"
        Me.Text = "Form2"
        Me.GroupBox1.ResumeLayout(False)
        Me.ResumeLayout(False)

    End Sub

#End Region

    ' The column currently used for sorting.
    Private m_SortingColumn As ColumnHeader

    ' Sort using the clicked column.
    Private Sub lvwBooks_ColumnClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.ColumnClickEventArgs) Handles lvwBooks.ColumnClick
        ' Get the new sorting column.
        Dim new_sorting_column As ColumnHeader = _
            lvwBooks.Columns(e.Column)

        ' Figure out the new sorting order.
        Dim sort_order As System.Windows.Forms.SortOrder
        If m_SortingColumn Is Nothing Then
            ' New column. Sort ascending.
            sort_order = SortOrder.Ascending
        Else
            ' See if this is the same column.
            If new_sorting_column.Equals(m_SortingColumn) Then
                ' Same column. Switch the sort order.
                If m_SortingColumn.Text.StartsWith("> ") Then
                    sort_order = SortOrder.Descending
                Else
                    sort_order = SortOrder.Ascending
                End If
            Else
                ' New column. Sort ascending.
                sort_order = SortOrder.Ascending
            End If

            ' Remove the old sort indicator.
            m_SortingColumn.Text = m_SortingColumn.Text.Substring(2)
        End If

        ' Display the new sort order.
        m_SortingColumn = new_sorting_column
        If sort_order = SortOrder.Ascending Then
            m_SortingColumn.Text = "> " & m_SortingColumn.Text
        Else
            m_SortingColumn.Text = "< " & m_SortingColumn.Text
        End If

        ' Create a comparer.
        lvwBooks.ListViewItemSorter = New ListViewComparer(e.Column, sort_order)

        ' Sort.
        lvwBooks.Sort()
    End Sub
    Private Sub LoadData()
        lvwBooks.View = View.Details
        lvwBooks.Sorting = SortOrder.None

        lvwBooks.Columns.Add("Name", 84, HorizontalAlignment.Left)
        lvwBooks.Columns.Add("Site", 84, HorizontalAlignment.Left)
        lvwBooks.Columns.Add("ISBN", 84, HorizontalAlignment.Left)

        ' Add data rows.

        Dim i As Integer
        For i = 0 To 3
            lvwBooks.Items.Add("Ready-to-Run Visual Basic Algorithms" & i & "")
            lvwBooks.Items(i).SubItems.Add("http://www.vb-helper.com/vba.htm" & i & "")
            lvwBooks.Items(i).SubItems.Add("0-471-24268-3" & i & "")
        Next i

        ' Size the columns.


        '' Size the columns.
        For j As Integer = 0 To lvwBooks.Columns.Count - 1
            lvwBooks.Columns(j).Width = -2
        Next j
    End Sub
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        ' Remove any existing items.


        lvwBooks.Items.Clear()
        LoadData()

    End Sub

    ' Make a ListView row.
    Private Sub ListViewMakeRow(ByVal lvw As ListView, ByVal item_title As String, ByVal ParamArray subitem_titles() As String)
        ' Make the item.
        Dim new_item As ListViewItem = lvw.Items.Add(item_title)

        ' Make the sub-items.
        For i As Integer = subitem_titles.GetLowerBound(0) To subitem_titles.GetUpperBound(0)
            new_item.SubItems.Add(subitem_titles(i))
        Next i
    End Sub


    Private Sub Reload_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnRefill.Click
        ' Remove any existing items.
        lvwBooks.Clear()
        LoadData()


    End Sub

End Class
Class ListViewComparer
    Implements IComparer

    Private m_ColumnNumber As Integer
    Private m_SortOrder As SortOrder

    Public Sub New(ByVal column_number As Integer, ByVal _
        sort_order As SortOrder)
        m_ColumnNumber = column_number
        m_SortOrder = sort_order
    End Sub

    ' Compare the items in the appropriate column
    ' for objects x and y.
    Public Function Compare(ByVal x As Object, ByVal y As _
        Object) As Integer Implements _
        System.Collections.IComparer.Compare
        Dim item_x As ListViewItem = DirectCast(x, _
            ListViewItem)
        Dim item_y As ListViewItem = DirectCast(y, _
            ListViewItem)

        ' Get the sub-item values.
        Dim string_x As String
        If item_x.SubItems.Count <= m_ColumnNumber Then
            string_x = ""
        Else
            string_x = item_x.SubItems(m_ColumnNumber).Text
        End If

        Dim string_y As String
        If item_y.SubItems.Count <= m_ColumnNumber Then
            string_y = ""
        Else
            string_y = item_y.SubItems(m_ColumnNumber).Text
        End If

        ' Compare them.
        If m_SortOrder = SortOrder.Ascending Then
            Return String.Compare(string_x, string_y)
        Else
            Return String.Compare(string_y, string_x)
        End If
    End Function

End Class
Instead of doing
lvwBooks.Items.Clear()

you should do this
lvwBooks.Clear()

sorry there is a problem with the above code
you should do both
lvwBooks.Items.Clear()
and then
lvwBooks.Clear()
ohh no sorry problem seems to be something else
hi  armoghan
i think we almost had it, but when i click on ISBN or  site once
and then refill i get the same error

thanks!
ASKER CERTIFIED SOLUTION
Avatar of armoghan
armoghan
Flag of Pakistan image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Yes the last one is working fine,
Its a work around but it is working OK with me
Have you tried the last one?
What I have done is
Before emptying the list, I have made the list in the same order as it was in the begining. So the insertion finds the same environment
:)
brilliant!
this prob had me going for a good while
thank you very much!
glad i could help :)