ListView: How to link columnheader into subitem
-
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?
-
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?
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
-
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?
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
-
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
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.
-
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.
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
-
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
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?
-
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?
-
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.
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 BooleanPublic 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 NamespaceIf you add a property to select witch columns may not be blocked it will do