Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. Visual Basic
  4. ListView: How to link columnheader into subitem

ListView: How to link columnheader into subitem

Scheduled Pinned Locked Moved Visual Basic
helptutorialquestion
8 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J Offline
    J Offline
    jtpaa
    wrote on last edited by
    #1

    Hi All, I'm using ListView to show several columns of data. (View = Details) Everything worked fine until I wanted to let the user to hide/show certain column(s). I hide the column this way: ListView1.Columns.Remove() Problem is to get the column correctly visible again, so that columnheaders are correctly ordered into subitem-columns. When I use ListView1.Columns.Insert() or ListView1.Columns.Add() to get the column visible again it links the columnheader to wrong subitem-column. Is there any way to link a columnheader into subitem-column?

    D 2 Replies Last reply
    0
    • J jtpaa

      Hi All, I'm using ListView to show several columns of data. (View = Details) Everything worked fine until I wanted to let the user to hide/show certain column(s). I hide the column this way: ListView1.Columns.Remove() Problem is to get the column correctly visible again, so that columnheaders are correctly ordered into subitem-columns. When I use ListView1.Columns.Insert() or ListView1.Columns.Add() to get the column visible again it links the columnheader to wrong subitem-column. Is there any way to link a columnheader into subitem-column?

      D Offline
      D Offline
      DaveAuld
      wrote on last edited by
      #2

      When you use remove, you are not hiding it, you are deleting it from the collection. When you use insert, you can specifying the position you want to add the column, have you tried that? Why not set the column width to 0 instead to hide it? that way it will remain in the same place.

      Dave Don't forget to vote on messages! Find Me On: Web|Facebook|Twitter|LinkedIn Waving? dave.m.auld[at]googlewave.com

      1 Reply Last reply
      0
      • J jtpaa

        Hi All, I'm using ListView to show several columns of data. (View = Details) Everything worked fine until I wanted to let the user to hide/show certain column(s). I hide the column this way: ListView1.Columns.Remove() Problem is to get the column correctly visible again, so that columnheaders are correctly ordered into subitem-columns. When I use ListView1.Columns.Insert() or ListView1.Columns.Add() to get the column visible again it links the columnheader to wrong subitem-column. Is there any way to link a columnheader into subitem-column?

        D Offline
        D Offline
        DaveAuld
        wrote on last edited by
        #3

        Further to my original response, i just did a quick test and can confirm that if you insert a column at the appropriate index, the subitems remain correctly with the columns; e.g. lv.removeat(2), lv.insert(2, "Col 3") As a quick demo, create a form, add a listview in details view, add three pushbuttons, drop in the following code and run the app;

        Private Sub Button1\_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            'Add some columns
            ListView1.Columns.Add("Col 1")
            ListView1.Columns.Add("Col 2")
            ListView1.Columns.Add("Col 3")
            ListView1.Columns.Add("Col 4")
        
            'Add some test data
            Dim x As New ListViewItem
            x.Text = "1"
            x.SubItems.Add("2")
            x.SubItems.Add("3")
            x.SubItems.Add("4")
            ListView1.Items.Add(x)
        End Sub
        
        Private Sub Button2\_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
            ListView1.Columns.RemoveAt(2)
        End Sub
        
        Private Sub Button3\_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
            ListView1.Columns.Insert(2, "col 3")
        End Sub
        

        And you will see the test data remains in the 1,2,3,4 sequence before and after the remove and insert operations.

        Dave Don't forget to vote on messages! Find Me On: Web|Facebook|Twitter|LinkedIn Waving? dave.m.auld[at]googlewave.com

        J 1 Reply Last reply
        0
        • D DaveAuld

          Further to my original response, i just did a quick test and can confirm that if you insert a column at the appropriate index, the subitems remain correctly with the columns; e.g. lv.removeat(2), lv.insert(2, "Col 3") As a quick demo, create a form, add a listview in details view, add three pushbuttons, drop in the following code and run the app;

          Private Sub Button1\_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
              'Add some columns
              ListView1.Columns.Add("Col 1")
              ListView1.Columns.Add("Col 2")
              ListView1.Columns.Add("Col 3")
              ListView1.Columns.Add("Col 4")
          
              'Add some test data
              Dim x As New ListViewItem
              x.Text = "1"
              x.SubItems.Add("2")
              x.SubItems.Add("3")
              x.SubItems.Add("4")
              ListView1.Items.Add(x)
          End Sub
          
          Private Sub Button2\_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
              ListView1.Columns.RemoveAt(2)
          End Sub
          
          Private Sub Button3\_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
              ListView1.Columns.Insert(2, "col 3")
          End Sub
          

          And you will see the test data remains in the 1,2,3,4 sequence before and after the remove and insert operations.

          Dave Don't forget to vote on messages! Find Me On: Web|Facebook|Twitter|LinkedIn Waving? dave.m.auld[at]googlewave.com

          J Offline
          J Offline
          jtpaa
          wrote on last edited by
          #4

          Thanks for Your answer. To hide a column via setting column width is not an option, because the user is and must be able to resize the column width. In Your example, if You first remove 2, 3 and 4 columns. And then insert only 4. column back, it causes an error. Problem is, that there are more subitems than there are columns. And in that case the columnheader can't necessarily be inserted over correct subitem.

          D J 2 Replies Last reply
          0
          • J jtpaa

            Thanks for Your answer. To hide a column via setting column width is not an option, because the user is and must be able to resize the column width. In Your example, if You first remove 2, 3 and 4 columns. And then insert only 4. column back, it causes an error. Problem is, that there are more subitems than there are columns. And in that case the columnheader can't necessarily be inserted over correct subitem.

            D Offline
            D Offline
            DaveAuld
            wrote on last edited by
            #5

            There does not appear to be anywayto map the subitems to columns. However this IS doable using the width. refere back to the orginal form example i gave earlier and add the code below; You will see, when you remove a column its width is set to 0 and added to a list of locked columns, then when the user tries to resize the locked column the columnresizing event checks if the column is in the locked collection, cancel the event and sets the width to 0.

            Public Class Form1

            Dim listLocked As New List(Of Integer) 'Locked columns
            
            Private Sub Button1\_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
                'Add some columns
                ListView1.Columns.Add("Col 1")
                ListView1.Columns.Add("Col 2")
                ListView1.Columns.Add("Col 3")
                ListView1.Columns.Add("Col 4")
            
                'Add some test data
                Dim x As New ListViewItem
                x.Text = "1"
                x.SubItems.Add("2")
                x.SubItems.Add("3")
                x.SubItems.Add("4")
                ListView1.Items.Add(x)
            End Sub
            
            Private Sub Button2\_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
                Dim colIndex As Integer = 2
                ListView1.Columns(colIndex).Width = 0
                If Not listLocked.Contains(colIndex) Then listLocked.Add(colIndex)
            End Sub
            
            Private Sub Button3\_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
                Dim colIndex As Integer = 2
                ListView1.Columns(colIndex).Width = 25
                If listLocked.Contains(colIndex) Then listLocked.Remove(colIndex)
            End Sub
            
            
            Private Sub ListView1\_ColumnWidthChanging(ByVal sender As Object, ByVal e As System.Windows.Forms.ColumnWidthChangingEventArgs) Handles ListView1.ColumnWidthChanging
                'Check column is not hidden
                If listLocked.Contains(e.ColumnIndex) Then
                    e.Cancel = True
                    e.NewWidth = 0
                End If
            
            End Sub
            

            End Class

            Dave Don't forget rate messages! Find Me On: Web|Facebook|Twitter|LinkedIn Waving? dave.m.auld[at]googlewave.com

            J 1 Reply Last reply
            0
            • D DaveAuld

              There does not appear to be anywayto map the subitems to columns. However this IS doable using the width. refere back to the orginal form example i gave earlier and add the code below; You will see, when you remove a column its width is set to 0 and added to a list of locked columns, then when the user tries to resize the locked column the columnresizing event checks if the column is in the locked collection, cancel the event and sets the width to 0.

              Public Class Form1

              Dim listLocked As New List(Of Integer) 'Locked columns
              
              Private Sub Button1\_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
                  'Add some columns
                  ListView1.Columns.Add("Col 1")
                  ListView1.Columns.Add("Col 2")
                  ListView1.Columns.Add("Col 3")
                  ListView1.Columns.Add("Col 4")
              
                  'Add some test data
                  Dim x As New ListViewItem
                  x.Text = "1"
                  x.SubItems.Add("2")
                  x.SubItems.Add("3")
                  x.SubItems.Add("4")
                  ListView1.Items.Add(x)
              End Sub
              
              Private Sub Button2\_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
                  Dim colIndex As Integer = 2
                  ListView1.Columns(colIndex).Width = 0
                  If Not listLocked.Contains(colIndex) Then listLocked.Add(colIndex)
              End Sub
              
              Private Sub Button3\_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
                  Dim colIndex As Integer = 2
                  ListView1.Columns(colIndex).Width = 25
                  If listLocked.Contains(colIndex) Then listLocked.Remove(colIndex)
              End Sub
              
              
              Private Sub ListView1\_ColumnWidthChanging(ByVal sender As Object, ByVal e As System.Windows.Forms.ColumnWidthChangingEventArgs) Handles ListView1.ColumnWidthChanging
                  'Check column is not hidden
                  If listLocked.Contains(e.ColumnIndex) Then
                      e.Cancel = True
                      e.NewWidth = 0
                  End If
              
              End Sub
              

              End Class

              Dave Don't forget rate messages! Find Me On: Web|Facebook|Twitter|LinkedIn Waving? dave.m.auld[at]googlewave.com

              J Offline
              J Offline
              jtpaa
              wrote on last edited by
              #6

              Yes, this seems to be the final solution. Actually I had this kind of solution earlier for hiding columns. But then something happened and ListView ColumnWidthChanging event stopped working. I mean that ColumnWidthChanging event does not fire att all. And I have not found any solution for that. Do You have any ideas how to get this ColumnWidthChanging-event problem fixed?

              D 1 Reply Last reply
              0
              • J jtpaa

                Yes, this seems to be the final solution. Actually I had this kind of solution earlier for hiding columns. But then something happened and ListView ColumnWidthChanging event stopped working. I mean that ColumnWidthChanging event does not fire att all. And I have not found any solution for that. Do You have any ideas how to get this ColumnWidthChanging-event problem fixed?

                D Offline
                D Offline
                DaveAuld
                wrote on last edited by
                #7

                No idea what would stop the columnwidthchanging event, other than some code you added to your original solution getting in the way.

                Dave Don't forget rate messages! Find Me On: Web|Facebook|Twitter|LinkedIn Waving? dave.m.auld[at]googlewave.com

                1 Reply Last reply
                0
                • J jtpaa

                  Thanks for Your answer. To hide a column via setting column width is not an option, because the user is and must be able to resize the column width. In Your example, if You first remove 2, 3 and 4 columns. And then insert only 4. column back, it causes an error. Problem is, that there are more subitems than there are columns. And in that case the columnheader can't necessarily be inserted over correct subitem.

                  J Offline
                  J Offline
                  JR212
                  wrote on last edited by
                  #8

                  Maybe if you block some columns to resize. This is my code to block them standard all with property to release some

                  Imports System.Runtime.InteropServices
                  Namespace Controls
                  Public Class ListView_FixColumns
                  Inherits ListView
                  Private _KolommenVrij(1024) As Boolean

                  Public Const WM\_NOTIFY As Integer = &H4E
                  Public Const HDN\_FIRST As Integer = 0 - 300
                  Public Const HDN\_BEGINTRACKA As Integer = HDN\_FIRST - 6
                  Public Const HDN\_BEGINTRACKW As Integer = HDN\_FIRST - 26
                  <StructLayout(LayoutKind.Sequential)> Public Structure NMHDR
                    Public hwndFrom As IntPtr
                    Public idFrom As Integer
                    Public code As Integer
                  End Structure
                  
                  Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
                    If m.Msg = WM\_NOTIFY Then
                      Dim hdr As NMHDR = CType(m.GetLParam(GetType(NMHDR)), NMHDR)
                      If hdr.code = HDN\_BEGINTRACKA OrElse hdr.code = HDN\_BEGINTRACKW OrElse hdr.code = HDN\_DIVIDERDBLCLICKW Then
                        Dim nmHeader As NMHEADER = CType(m.GetLParam(GetType(NMHEADER)), NMHEADER)
                        If Not \_FreeColumns(nmHeader.iItem) Then
                          m.Result = New IntPtr(1)
                          Exit Sub
                        End If
                      End If
                    End If
                    MyBase.WndProc(m)
                  End Sub  
                  Public Property AllowColumnResize(ByVal Column As Integer) As Boolean
                    Get
                      Return \_KolommenVrij(Column)
                    End Get
                    Set(ByVal value As Boolean)
                      \_KolommenVrij(Column) = value
                    End Set
                  End Property
                  

                  End Class
                  End Namespace

                  If you add a property to select witch columns may not be blocked it will do

                  1 Reply Last reply
                  0
                  Reply
                  • Reply as topic
                  Log in to reply
                  • Oldest to Newest
                  • Newest to Oldest
                  • Most Votes


                  • Login

                  • Don't have an account? Register

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • World
                  • Users
                  • Groups