gozza11
asked on
items.clear not working to clear listview?
for some strange reason i can resize my form and clear the items yet every now and then it crashes tellin me "Object reference not set to an instance of an object"??
i have posted the code below but im not sure why it shouldnt work because it does for a litle while and then crashes afterwards.
Thanks
Gozza
here is the code:
-------------------------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------
Public PreviousVItemCount As String
Public TestArray(40) As ListViewItem
Public FormLoaded As Boolean = False
Public Sub Populate()
With lvwLibrary2
Dim i As Integer
Dim ColWidth As Integer
Dim VitemCount As String
For i = 0 To .Columns.Count - 1
ColWidth += .Columns(i).Width
Next
If ColWidth > .Width Then
VitemCount = (.Height - 39) / 14
Else
VitemCount = (.Height - 19) / 14
End If
If VitemCount.IndexOf(".") > 0 Then
VitemCount = VitemCount.Substring(0, VitemCount.IndexOf("."))
ElseIf VitemCount.IndexOf(".") = 0 Then
VitemCount = 0
End If
If Not VitemCount = PreviousVItemCount Then
scrollV.Maximum = TestArray.Length + 8
If .Items.Count > 0 Then
.Items.Clear()
End If
For i = 0 To VitemCount - 1
Try
.Items.Add(TestArray(scrol lV.Value + i).Clone)
Catch ex As Exception
MsgBox(ex.Message)
End Try
Next
PreviousVItemCount = VitemCount
End If
End With
End Sub
Public Sub Scroll()
With lvwLibrary2
If scrollV.Value < OldValue Then
.Items(.Items.Count - 1).Remove()
.Items.Insert(0, TestArray(scrollV.Value).C lone)
ElseIf scrollV.Value > OldValue Then
.Items(0).Remove()
.Items.Add(TestArray(scrol lV.Value). Clone)
End If
OldValue = scrollV.Value
End With
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Populate() 'this works fine, only crashes when it resizes
End Sub
Private Sub scrollV_Scroll(ByVal sender As System.Object, ByVal e As System.Windows.Forms.Scrol lEventArgs ) Handles scrollV.Scroll
Scroll()
End Sub
Private Sub lvwLibrary2_SizeChanged(By Val sender As Object, ByVal e As System.EventArgs) Handles lvwLibrary2.SizeChanged
If FormLoaded Then
Populate()
End If
End Sub
Private Sub frmOptions_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim i As Integer
For i = 0 To 40
Dim item As New ListViewItem
item.Text = "test - " & i
item.SubItems.Add("test - " & i)
TestArray(i) = item
Next
FormLoaded = True
End Sub
-------------------------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- -----
i have posted the code below but im not sure why it shouldnt work because it does for a litle while and then crashes afterwards.
Thanks
Gozza
here is the code:
--------------------------
Public PreviousVItemCount As String
Public TestArray(40) As ListViewItem
Public FormLoaded As Boolean = False
Public Sub Populate()
With lvwLibrary2
Dim i As Integer
Dim ColWidth As Integer
Dim VitemCount As String
For i = 0 To .Columns.Count - 1
ColWidth += .Columns(i).Width
Next
If ColWidth > .Width Then
VitemCount = (.Height - 39) / 14
Else
VitemCount = (.Height - 19) / 14
End If
If VitemCount.IndexOf(".") > 0 Then
VitemCount = VitemCount.Substring(0, VitemCount.IndexOf("."))
ElseIf VitemCount.IndexOf(".") = 0 Then
VitemCount = 0
End If
If Not VitemCount = PreviousVItemCount Then
scrollV.Maximum = TestArray.Length + 8
If .Items.Count > 0 Then
.Items.Clear()
End If
For i = 0 To VitemCount - 1
Try
.Items.Add(TestArray(scrol
Catch ex As Exception
MsgBox(ex.Message)
End Try
Next
PreviousVItemCount = VitemCount
End If
End With
End Sub
Public Sub Scroll()
With lvwLibrary2
If scrollV.Value < OldValue Then
.Items(.Items.Count - 1).Remove()
.Items.Insert(0, TestArray(scrollV.Value).C
ElseIf scrollV.Value > OldValue Then
.Items(0).Remove()
.Items.Add(TestArray(scrol
End If
OldValue = scrollV.Value
End With
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Populate() 'this works fine, only crashes when it resizes
End Sub
Private Sub scrollV_Scroll(ByVal sender As System.Object, ByVal e As System.Windows.Forms.Scrol
Scroll()
End Sub
Private Sub lvwLibrary2_SizeChanged(By
If FormLoaded Then
Populate()
End If
End Sub
Private Sub frmOptions_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim i As Integer
For i = 0 To 40
Dim item As New ListViewItem
item.Text = "test - " & i
item.SubItems.Add("test - " & i)
TestArray(i) = item
Next
FormLoaded = True
End Sub
--------------------------
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Hai,
Check the below code... It's working great.
The problem with your code is Populate() function is running multiple times as it's called on lvwLibrary2_SizeChanged event. So i've added a boolean variable ivlLodingList to check whether populate() function is running if not it will get called.
Public Class SystemTray
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.ICon tainer
'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.
Private WithEvents NotifyIcon1 As System.Windows.Forms.Notif yIcon
Friend WithEvents ContextMenu1 As System.Windows.Forms.Conte xtMenu
Friend WithEvents mnuShow As System.Windows.Forms.MenuI tem
Friend WithEvents mnuHide As System.Windows.Forms.MenuI tem
Friend WithEvents lvwLibrary2 As System.Windows.Forms.ListV iew
Friend WithEvents Button1 As System.Windows.Forms.Butto n
Friend WithEvents scrollV As System.Windows.Forms.VScro llBar
Friend WithEvents ColumnHeader1 As System.Windows.Forms.Colum nHeader
Friend WithEvents ColumnHeader2 As System.Windows.Forms.Colum nHeader
<System.Diagnostics.Debugg erStepThro ugh()> Private Sub InitializeComponent()
Me.components = New System.ComponentModel.Cont ainer
Dim resources As System.Resources.ResourceM anager = New System.Resources.ResourceM anager(Get Type(Syste mTray))
Me.NotifyIcon1 = New System.Windows.Forms.Notif yIcon(Me.c omponents)
Me.ContextMenu1 = New System.Windows.Forms.Conte xtMenu
Me.mnuShow = New System.Windows.Forms.MenuI tem
Me.mnuHide = New System.Windows.Forms.MenuI tem
Me.lvwLibrary2 = New System.Windows.Forms.ListV iew
Me.Button1 = New System.Windows.Forms.Butto n
Me.scrollV = New System.Windows.Forms.VScro llBar
Me.ColumnHeader1 = New System.Windows.Forms.Colum nHeader
Me.ColumnHeader2 = New System.Windows.Forms.Colum nHeader
Me.SuspendLayout()
'
'NotifyIcon1
'
Me.NotifyIcon1.ContextMenu = Me.ContextMenu1
Me.NotifyIcon1.Icon = CType(resources.GetObject( "NotifyIco n1.Icon"), System.Drawing.Icon)
Me.NotifyIcon1.Text = "Notify"
Me.NotifyIcon1.Visible = True
'
'ContextMenu1
'
Me.ContextMenu1.MenuItems. AddRange(N ew System.Windows.Forms.MenuI tem() {Me.mnuShow, Me.mnuHide})
'
'mnuShow
'
Me.mnuShow.Index = 0
Me.mnuShow.Text = "Show"
'
'mnuHide
'
Me.mnuHide.Index = 1
Me.mnuHide.Text = "Hide"
'
'lvwLibrary2
'
Me.lvwLibrary2.Columns.Add Range(New System.Windows.Forms.Colum nHeader() {Me.ColumnHeader1, Me.ColumnHeader2})
Me.lvwLibrary2.Location = New System.Drawing.Point(8, 8)
Me.lvwLibrary2.Name = "lvwLibrary2"
Me.lvwLibrary2.Size = New System.Drawing.Size(272, 216)
Me.lvwLibrary2.TabIndex = 0
Me.lvwLibrary2.View = System.Windows.Forms.View. Details
'
'Button1
'
Me.Button1.Location = New System.Drawing.Point(216, 248)
Me.Button1.Name = "Button1"
Me.Button1.Size = New System.Drawing.Size(64, 24)
Me.Button1.TabIndex = 1
Me.Button1.Text = "Button1"
'
'scrollV
'
Me.scrollV.Location = New System.Drawing.Point(280, 8)
Me.scrollV.Name = "scrollV"
Me.scrollV.Size = New System.Drawing.Size(16, 216)
Me.scrollV.TabIndex = 2
'
'ColumnHeader1
'
Me.ColumnHeader1.Width = 94
'
'ColumnHeader2
'
Me.ColumnHeader2.Width = 109
'
'SystemTray
'
Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
Me.ClientSize = New System.Drawing.Size(320, 273)
Me.Controls.Add(Me.scrollV )
Me.Controls.Add(Me.Button1 )
Me.Controls.Add(Me.lvwLibr ary2)
Me.Name = "SystemTray"
Me.Text = "SystemTray"
Me.ResumeLayout(False)
End Sub
#End Region
Public PreviousVItemCount As String
Public TestArray(40) As ListViewItem
Public FormLoaded As Boolean = False
Dim OldValue As Integer = 0, ivlLodingList As Boolean = False
Public Sub Populate()
With lvwLibrary2
Dim i As Integer
Dim ColWidth As Integer
Dim VitemCount As String
For i = 0 To .Columns.Count - 1
ColWidth += .Columns(i).Width
Next
If ColWidth > .Width Then
VitemCount = (.Height - 39) / 14
Else
VitemCount = (.Height - 19) / 14
End If
If VitemCount.IndexOf(".") > 0 Then
VitemCount = VitemCount.Substring(0, VitemCount.IndexOf("."))
ElseIf VitemCount.IndexOf(".") = 0 Then
VitemCount = 0
End If
If Not VitemCount = PreviousVItemCount Then
scrollV.Maximum = TestArray.Length + 8
If .Items.Count > 0 Then
.Items.Clear()
End If
For i = 0 To VitemCount - 1
Try
.Items.Add(TestArray(scrol lV.Value + i))
Catch ex As Exception
MsgBox(ex.Message)
End Try
Next
PreviousVItemCount = VitemCount
End If
End With
End Sub
Public Sub Scroll()
With lvwLibrary2
If Me.lvwLibrary2.Items.Count > 0 Then
If scrollV.Value < OldValue Then
.Items(.Items.Count - 1).Remove()
.Items.Insert(0, TestArray(scrollV.Value).C lone)
ElseIf scrollV.Value > OldValue Then
.Items(0).Remove()
.Items.Add(TestArray(scrol lV.Value). Clone)
End If
OldValue = scrollV.Value
End If
End With
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
ivlLodingList = True 'initialize a variable to true so that populate() will not get reloaded on loop
Populate() 'this works fine, only crashes when it resizes
ivlLodingList = False
End Sub
Private Sub scrollV_Scroll(ByVal sender As System.Object, ByVal e As System.Windows.Forms.Scrol lEventArgs ) Handles scrollV.Scroll
Scroll()
End Sub
Private Sub lvwLibrary2_SizeChanged(By Val sender As Object, ByVal e As System.EventArgs) Handles lvwLibrary2.SizeChanged
If FormLoaded And ivlLodingList = False Then 'Check whether Populate() is running
ivlLodingList = True 'initialize a variable to true so that populate() will not get reloaded on loop
Populate()
ivlLodingList = False
End If
End Sub
Private Sub frmOptions_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim i As Integer
For i = 0 To 40
Dim item As New ListViewItem
item.Text = "test - " & i
item.SubItems.Add("test - " & i)
TestArray(i) = item.Clone()
Next
FormLoaded = True
End Sub
End Class
Bye
Ajai
Check the below code... It's working great.
The problem with your code is Populate() function is running multiple times as it's called on lvwLibrary2_SizeChanged event. So i've added a boolean variable ivlLodingList to check whether populate() function is running if not it will get called.
Public Class SystemTray
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.ICon
'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.
Private WithEvents NotifyIcon1 As System.Windows.Forms.Notif
Friend WithEvents ContextMenu1 As System.Windows.Forms.Conte
Friend WithEvents mnuShow As System.Windows.Forms.MenuI
Friend WithEvents mnuHide As System.Windows.Forms.MenuI
Friend WithEvents lvwLibrary2 As System.Windows.Forms.ListV
Friend WithEvents Button1 As System.Windows.Forms.Butto
Friend WithEvents scrollV As System.Windows.Forms.VScro
Friend WithEvents ColumnHeader1 As System.Windows.Forms.Colum
Friend WithEvents ColumnHeader2 As System.Windows.Forms.Colum
<System.Diagnostics.Debugg
Me.components = New System.ComponentModel.Cont
Dim resources As System.Resources.ResourceM
Me.NotifyIcon1 = New System.Windows.Forms.Notif
Me.ContextMenu1 = New System.Windows.Forms.Conte
Me.mnuShow = New System.Windows.Forms.MenuI
Me.mnuHide = New System.Windows.Forms.MenuI
Me.lvwLibrary2 = New System.Windows.Forms.ListV
Me.Button1 = New System.Windows.Forms.Butto
Me.scrollV = New System.Windows.Forms.VScro
Me.ColumnHeader1 = New System.Windows.Forms.Colum
Me.ColumnHeader2 = New System.Windows.Forms.Colum
Me.SuspendLayout()
'
'NotifyIcon1
'
Me.NotifyIcon1.ContextMenu
Me.NotifyIcon1.Icon = CType(resources.GetObject(
Me.NotifyIcon1.Text = "Notify"
Me.NotifyIcon1.Visible = True
'
'ContextMenu1
'
Me.ContextMenu1.MenuItems.
'
'mnuShow
'
Me.mnuShow.Index = 0
Me.mnuShow.Text = "Show"
'
'mnuHide
'
Me.mnuHide.Index = 1
Me.mnuHide.Text = "Hide"
'
'lvwLibrary2
'
Me.lvwLibrary2.Columns.Add
Me.lvwLibrary2.Location = New System.Drawing.Point(8, 8)
Me.lvwLibrary2.Name = "lvwLibrary2"
Me.lvwLibrary2.Size = New System.Drawing.Size(272, 216)
Me.lvwLibrary2.TabIndex = 0
Me.lvwLibrary2.View = System.Windows.Forms.View.
'
'Button1
'
Me.Button1.Location = New System.Drawing.Point(216, 248)
Me.Button1.Name = "Button1"
Me.Button1.Size = New System.Drawing.Size(64, 24)
Me.Button1.TabIndex = 1
Me.Button1.Text = "Button1"
'
'scrollV
'
Me.scrollV.Location = New System.Drawing.Point(280, 8)
Me.scrollV.Name = "scrollV"
Me.scrollV.Size = New System.Drawing.Size(16, 216)
Me.scrollV.TabIndex = 2
'
'ColumnHeader1
'
Me.ColumnHeader1.Width = 94
'
'ColumnHeader2
'
Me.ColumnHeader2.Width = 109
'
'SystemTray
'
Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
Me.ClientSize = New System.Drawing.Size(320, 273)
Me.Controls.Add(Me.scrollV
Me.Controls.Add(Me.Button1
Me.Controls.Add(Me.lvwLibr
Me.Name = "SystemTray"
Me.Text = "SystemTray"
Me.ResumeLayout(False)
End Sub
#End Region
Public PreviousVItemCount As String
Public TestArray(40) As ListViewItem
Public FormLoaded As Boolean = False
Dim OldValue As Integer = 0, ivlLodingList As Boolean = False
Public Sub Populate()
With lvwLibrary2
Dim i As Integer
Dim ColWidth As Integer
Dim VitemCount As String
For i = 0 To .Columns.Count - 1
ColWidth += .Columns(i).Width
Next
If ColWidth > .Width Then
VitemCount = (.Height - 39) / 14
Else
VitemCount = (.Height - 19) / 14
End If
If VitemCount.IndexOf(".") > 0 Then
VitemCount = VitemCount.Substring(0, VitemCount.IndexOf("."))
ElseIf VitemCount.IndexOf(".") = 0 Then
VitemCount = 0
End If
If Not VitemCount = PreviousVItemCount Then
scrollV.Maximum = TestArray.Length + 8
If .Items.Count > 0 Then
.Items.Clear()
End If
For i = 0 To VitemCount - 1
Try
.Items.Add(TestArray(scrol
Catch ex As Exception
MsgBox(ex.Message)
End Try
Next
PreviousVItemCount = VitemCount
End If
End With
End Sub
Public Sub Scroll()
With lvwLibrary2
If Me.lvwLibrary2.Items.Count
If scrollV.Value < OldValue Then
.Items(.Items.Count - 1).Remove()
.Items.Insert(0, TestArray(scrollV.Value).C
ElseIf scrollV.Value > OldValue Then
.Items(0).Remove()
.Items.Add(TestArray(scrol
End If
OldValue = scrollV.Value
End If
End With
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
ivlLodingList = True 'initialize a variable to true so that populate() will not get reloaded on loop
Populate() 'this works fine, only crashes when it resizes
ivlLodingList = False
End Sub
Private Sub scrollV_Scroll(ByVal sender As System.Object, ByVal e As System.Windows.Forms.Scrol
Scroll()
End Sub
Private Sub lvwLibrary2_SizeChanged(By
If FormLoaded And ivlLodingList = False Then 'Check whether Populate() is running
ivlLodingList = True 'initialize a variable to true so that populate() will not get reloaded on loop
Populate()
ivlLodingList = False
End If
End Sub
Private Sub frmOptions_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim i As Integer
For i = 0 To 40
Dim item As New ListViewItem
item.Text = "test - " & i
item.SubItems.Add("test - " & i)
TestArray(i) = item.Clone()
Next
FormLoaded = True
End Sub
End Class
Bye
Ajai
OK, here's an example. I'm assuming your ListView has two columns. You would define a structure like this:
Public Structure DataItem
Public item1 As String
Public item2 As String
Public Function ToListViewItem() As ListViewItem
Dim lvi As New ListViewItem(item1)
lvi.SubItems.Add(item2)
Return lvi
End Function
End Structure
Now, you would have to modify TestArray to be an array of DataItem, and change your For loop like so:
For i = 0 To 40
Dim item As New DataItem
item.item1 = "test - " & i
item.item2 = "test - " & i
TestArray(i) = item
Next
When you want to add all items in the array to the ListView, you would simply do
For Each item as DataItem in TestArray
lvwLibrary2.Items.Add(item .ToListVie wItem)
Next
This seems roundabout, but it accomplishes a few things. First, it stores your data in a format that is both easy for you to work with and easy to convert to the display format you want. Second, since DataItem is separate from the ListViewItem, you can do whatever you want with the ListViewItem without having to worry about whether you are changing the array.
Public Structure DataItem
Public item1 As String
Public item2 As String
Public Function ToListViewItem() As ListViewItem
Dim lvi As New ListViewItem(item1)
lvi.SubItems.Add(item2)
Return lvi
End Function
End Structure
Now, you would have to modify TestArray to be an array of DataItem, and change your For loop like so:
For i = 0 To 40
Dim item As New DataItem
item.item1 = "test - " & i
item.item2 = "test - " & i
TestArray(i) = item
Next
When you want to add all items in the array to the ListView, you would simply do
For Each item as DataItem in TestArray
lvwLibrary2.Items.Add(item
Next
This seems roundabout, but it accomplishes a few things. First, it stores your data in a format that is both easy for you to work with and easy to convert to the display format you want. Second, since DataItem is separate from the ListViewItem, you can do whatever you want with the ListViewItem without having to worry about whether you are changing the array.
ASKER
thanks
goz