locked
Listview - Problems with with listview.selectedindexchanged RRS feed

  • Question

  • I have a listview (named lvMaterials), i populate with data from a XML-file. Currently I have one column, and I have set multiselect=false (as the listview is used to select the needed material for a workpiece. the selection triggers a second listview to be filled with data).

    When the form loads, and the data is added to the listview, I want my code to select (and highlight) the item that fits a specific value (the current material assigned to the workpiece).

    A second listview (lvDimensions) is filled with data based on the  selection from lvMaterials. In this, I also want to select and highlight a specific value.

    The code works only in the scenario where the userform is loaded. When I try to select a new value in lvMaterials, I get an error:

    "System.NullReferenceException: 'Objektreferencen er ikke indstillet til en forekomst af et objekt.'

    System.Windows.Forms.ListView.FocusedItem.get returned Nothing."

    The error must relate to 

    LvMaterials.FocusedItem.Text

    under the itemselectchanged, but I can't figure out how to solve it.

    Code that selects items in the listviews:

     Private Sub LoadMaterial()
            ' On Error Resume Next
            '--- Declare Custom iProperties
            Dim customPropSet As PropertySet = SharedVariables.oDoc.PropertySets.Item("Inventor User Defined Properties")
            Dim TypeCat As String = customPropSet.Item("Type_Category").Value
            TypeCat = TypeCat.Replace(" ", "")
    
    
            '---------------------------- Load XML file ------------------------------------'
            'Filename with materials: xmlMatLibrary
            Dim xmlDoc As New XmlDocument()
            xmlDoc.Load("D:\Autodesk\Robot Kinematics\XML\xmlMatLibrary.xml")
            Dim nodes As XmlNodeList = xmlDoc.DocumentElement.SelectNodes("/materiallibrary/material")
    
            'Fill data into lvMaterials:
            For Each node As XmlNode In nodes
                If node.Attributes("template").InnerText = TypeCat Then
                    If LvMaterials.FindItemWithText(node.SelectSingleNode("inventormaterial").InnerText) Is Nothing Then
                        LvMaterials.Items.Add(node.SelectSingleNode("inventormaterial").InnerText)
                    End If
                End If
            Next
    
            Dim ProfType As String = customPropSet.Item("Profile_Type").Value
            Dim matName As String = SharedVariables.oDoc.ComponentDefinition.Material.Name
            Dim searchMat As ListViewItem = LvMaterials.FindItemWithText(matName)
    
            If Not searchMat Is Nothing Then
                searchMat.Focused = True
                searchMat.Selected = True
                searchMat.EnsureVisible()
                LvMaterials.Select()
            End If
    
            If Not LvDimensions.FindItemWithText(ProfType) Is Nothing Then
                Dim searchDim As ListViewItem = LvDimensions.FindItemWithText(ProfType)
                searchDim.Focused = True
                searchDim.Selected = True
                searchDim.EnsureVisible()
                LvDimensions.Select()
            End If


        Private Sub LvMaterials_ItemSelectionChanged(sender As Object, e As ListViewItemSelectionChangedEventArgs) Handles LvMaterials.ItemSelectionChanged
            'This code triggers, when a new index is selected
            '  On Error Resume Next
    
            ' LvMaterials.SelectedItems.Clear()
    
            Dim xmlDoc As New XmlDocument()
            xmlDoc.Load("D:\Autodesk\Robot Kinematics\XML\xmlMatLibrary.xml")
            Dim nodes As XmlNodeList = xmlDoc.DocumentElement.SelectNodes("/materiallibrary/material")
    
            LvDimensions.Items.Clear()
    
            For Each node As XmlNode In nodes
    
                If node.SelectSingleNode("inventormaterial").InnerText = LvMaterials.FocusedItem.Text And node.Attributes("template").InnerText = "RectangularMassive" Then
                    Dim newType As New ListViewItem(node.SelectSingleNode("type").InnerText)
                    newType.SubItems.Add(node.SelectSingleNode("pricecategory").InnerText)
                    LvDimensions.Items.Add(newType)
                End If
            Next
    
            '  ListView2.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent)
        End Sub


    The fix to get my code running is to clear the selection when the lvMaterials.itemselectedChanged (or lvMaterials.selectedindexchanged) with this line: 

    LvMaterials.SelectedItems.Clear()

    The problem with this tho, is that I can't highlight the items in the listviews:

    I hope you can see where I make the error, as the highlights for the selected materials are important for the users.

    I would have posted, pictures, but I need validation.

    Sunday, May 12, 2019 1:22 PM

Answers

  • Hi, thanks for the answer.

    In vb.net listviews there are nothing called selecteditem. there are selecteditems().item() and so on. I have tried loads of combinations with selectedindecies, selecteditems, but each one of them fail when I manually select a value in lvMaterials.

    But finally I found a solution on the forum - Not that I havent tried:

    https://social.msdn.microsoft.com/Forums/vstudio/en-US/5d52fcef-e1b9-4a25-8288-28696391a5dc/how-to-get-the-selected-index-in-listview?forum=vbgeneral

    Same issue, same solution

    Solution code:

       Dim index As Integer = 0
       If ListView1.SelectedItems.Count > 0 Then
           index = ListView1.SelectedItems(0).Index
    
       End If
    
    For Each node As XmlNode In nodes
    
                If node.SelectSingleNode("inventormaterial").InnerText = LvMaterials.Items(index).Text And node.Attributes("template").InnerText = TypeCat Then
                    Dim newType As New ListViewItem(node.SelectSingleNode("type").InnerText)
                    newType.SubItems.Add(node.SelectSingleNode("pricecategory").InnerText)
                    LvDimensions.Items.Add(newType)
                End If
            Next

    • Edited by Kepano_DK Sunday, May 12, 2019 3:19 PM
    • Marked as answer by Kepano_DK Sunday, May 12, 2019 6:54 PM
    Sunday, May 12, 2019 3:16 PM

All replies

  • Hi

    The line you say may be producing the error doesn't seem to be in the code you posted. Why are you using that instead of .SelectedItem?

    The only thing I can think of is this text from MS where you *might* be getting a null with the

    LvMaterials.FocusedItem

    as the focuseditem can be null.

    Quote: Although an item may be the one displaying the focus reticle, it may not actually be a selected item in the ListView.




    Regards Les, Livingston, Scotland

    Sunday, May 12, 2019 1:51 PM
  • Hi, thanks for the answer.

    In vb.net listviews there are nothing called selecteditem. there are selecteditems().item() and so on. I have tried loads of combinations with selectedindecies, selecteditems, but each one of them fail when I manually select a value in lvMaterials.

    But finally I found a solution on the forum - Not that I havent tried:

    https://social.msdn.microsoft.com/Forums/vstudio/en-US/5d52fcef-e1b9-4a25-8288-28696391a5dc/how-to-get-the-selected-index-in-listview?forum=vbgeneral

    Same issue, same solution

    Solution code:

       Dim index As Integer = 0
       If ListView1.SelectedItems.Count > 0 Then
           index = ListView1.SelectedItems(0).Index
    
       End If
    
    For Each node As XmlNode In nodes
    
                If node.SelectSingleNode("inventormaterial").InnerText = LvMaterials.Items(index).Text And node.Attributes("template").InnerText = TypeCat Then
                    Dim newType As New ListViewItem(node.SelectSingleNode("type").InnerText)
                    newType.SubItems.Add(node.SelectSingleNode("pricecategory").InnerText)
                    LvDimensions.Items.Add(newType)
                End If
            Next

    • Edited by Kepano_DK Sunday, May 12, 2019 3:19 PM
    • Marked as answer by Kepano_DK Sunday, May 12, 2019 6:54 PM
    Sunday, May 12, 2019 3:16 PM
  • Hi

    I think, from your last post, that you have found a solution.

    Just for completions, here is some code I preciously used in another question. It selects an item in a ListView, based on an item selected in a ListBox selection (and vice versa). I cant reproduce the issue you are (were?) seeing, but this code seems to do something close to what you want (maybe).

    If you do already have a solution then just ignore this post. The example code is in the form of a stand alone project.

    ' LISTVIEW SELECTION
    ' SUBITEMS DISPLAY
    ' LISTBOX SELECTION
    
    ' Blank Form1
    Option Strict On
    Option Explicit On
    Public Class Form1
        Dim WithEvents listView1 As New ListView()
        Dim WithEvents listbox1 As New ListBox
        Dim Label1 As New Label
        Dim LBdatasource As New List(Of String)
        Dim rand As New Random
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            DoubleBuffered = True
            CreateMyListView(listView1)
            CreateMyListBox()
            CreateLabel()
            listbox1.DataSource = LBdatasource
            Controls.AddRange({listView1, listbox1, Label1})
        End Sub
        Sub CreateLabel()
            With Label1
                .AutoSize = False
                .Location = New Point(10, listView1.Bottom + 4)
                .Width = ClientSize.Width - 20
                .BackColor = Color.LightPink
                .Anchor = AnchorStyles.Bottom Or AnchorStyles.Left Or AnchorStyles.Right
            End With
        End Sub
        Sub CreateMyListBox()
            With listbox1
                ' set loc
                .Location = New Point(ClientSize.Width \ 2 + 5, 5)
                ' set size
                .Size = New Size(ClientSize.Width \ 2 - 5, ClientSize.Height - 40)
                .IntegralHeight = False
                .Anchor = AnchorStyles.Top Or AnchorStyles.Bottom Or AnchorStyles.Right
            End With
        End Sub
        Private Sub CreateMyListView(lv As ListView)
            ' Create new ListView.
            With lv
                ' set loc
                .Location = New Point(5, 5)
                ' set size
                .Size = New Size(ClientSize.Width \ 2 - 5, ClientSize.Height - 40)
                ' Set to details.
                .View = View.Details
                ' Allow item edit.
                .LabelEdit = True
                ' Allow rearrange columns.
                .AllowColumnReorder = True
                ' check boxes.
                .CheckBoxes = True
                ' Select a range of Items
                .MultiSelect = False
                ' Select whole row.
                .FullRowSelect = True
                ' Show grid lines.
                .GridLines = True
                .Columns.Add("Item Column", -2, HorizontalAlignment.Left)
                .Columns.Add("Column 2", -2, HorizontalAlignment.Left)
                .Columns.Add("Column 3", -2, HorizontalAlignment.Left)
                .Columns.Add("Column 4", -2, HorizontalAlignment.Center)
                .Columns.Add("Column 5", -2, HorizontalAlignment.Center)
                .Columns.Add("Column 6", -2, HorizontalAlignment.Center)
    
                .Anchor = AnchorStyles.Top Or AnchorStyles.Bottom Or AnchorStyles.Left Or AnchorStyles.Right
    
                ' make some dummy test data
                For itm As Integer = 1 To 19
                    Dim item As New ListViewItem("item" & itm.ToString, rand.Next(0, 2))
                    Dim tf As Boolean = True
                    If rand.Next(0, 2) = 1 Then tf = False
                    item.Checked = tf
                    item.SubItems.Add((rand.NextDouble * rand.Next(100, 199)).ToString("0.00"))
                    item.SubItems.Add((rand.NextDouble * rand.Next(200, 299)).ToString("0.00"))
                    item.SubItems.Add((rand.NextDouble * rand.Next(300, 399)).ToString("0.00"))
                    item.SubItems.Add((rand.NextDouble * rand.Next(300, 399)).ToString("0.00"))
                    item.SubItems.Add((rand.NextDouble * rand.Next(300, 399)).ToString("0.00"))
                    LBdatasource.Add(item.Text)
                    .Items.Add(item)
                Next
            End With
        End Sub
        Private Sub listView1_MouseMove(sender As Object, e As MouseEventArgs) Handles listView1.MouseMove
            Static intLast As Integer = 0
            Dim htInfo As ListViewHitTestInfo
            If Not listView1.View = View.Details Then
                listView1.Items(intLast).BackColor = listView1.BackColor
            Else
                htInfo = listView1.HitTest(e.Location)
    
                If Not htInfo.Item Is Nothing Then
    
                    If htInfo.Item.Index <> intLast Then
                        listView1.Items(intLast).Selected = False
                        htInfo.Item.Selected = True
                        intLast = htInfo.Item.Index
                    End If
                End If
            End If
        End Sub
        Private Sub ListBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles listbox1.SelectedIndexChanged
            Label1.Text = Nothing
            Dim lb As ListBox = DirectCast(sender, ListBox)
            Dim item As ListViewItem
            item = listView1.FindItemWithText(lb.SelectedItem.ToString)
            item.Focused = True
            item.Selected = True
            For Each si As ListViewItem.ListViewSubItem In item.SubItems
                Label1.Text &= si.Text & Space(3)
            Next
            listView1.Select()
        End Sub
        Private Sub ListView1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles listView1.SelectedIndexChanged
            Dim lv As ListView = DirectCast(sender, ListView)
            If lv.SelectedItems.Count < 1 Then Exit Sub
            Dim SelItem As String = lv.SelectedItems(0).Text
            listbox1.SelectedItem = SelItem
        End Sub
    End Class
    


    Regards Les, Livingston, Scotland

    Sunday, May 12, 2019 4:27 PM
  • When I try to select a new value in lvMaterials, I get an error:

    "System.NullReferenceException: 'Objektreferencen er ikke indstillet til en forekomst af et objekt.'

    System.Windows.Forms.ListView.FocusedItem.get returned Nothing."

    See ListView.ItemSelectionChanged Event; it says the ItemSelectionChanged event occurs whether the item state changes from selected to deselected or deselected to selected. So the first firing is for the deselection so of course nothing is selected. A possible solution is to use IsSelected.



    Sam Hobbs
    SimpleSamples.Info

    Sunday, May 12, 2019 5:40 PM
  • Hi, thanks for the answer.

    When you put it that way it makes sense. I guess I was getting frustrated.

    I can't find the .isSelected for the Listview - but for the others; Datagrid, listboxitem have it.

    Sunday, May 12, 2019 6:52 PM
  • Thanks, I'll try read it through and see if I get an understanding of it.

    For now, I'll consider the problem solved.

    Sunday, May 12, 2019 6:54 PM