AllowColumnReorder used programmatically

V

VR

Please, help.

Is there any way to take advantage of re-ordering columns
in ListView control programmatically when
AllowColumnReorder is set to true?

I have a ListView with 3 columns, LabelEdit is set to
true. That allows user to edit 0th column. I want the user
to be able to edit the 1st (or the middle) column. I
figured my item (0th) column should be somehow switched
with the 1st sub-item's column.

It's pretty easy to do by setting AllowColumnReorder to
true and then, manually re-orderding columns by drag-and-
dropping them.

Is there any way to do it programmatically without user
intervention?

Thanks.
VR
 
P

Parker Zhang [MSFT]

Hi,

Sending the lvm_setcolumnorderarray message to the listview along with
an array that specifies the left to right order of the columns will allow
you to
programatically change the order of the columns in the listview. The
ListView view
should be set to Details

Here is VB.NET code. I think you can easily convert it to C#.

'Sendmessage declare
Const LVM_FIRST As Integer = &H1000
Const LVM_SETCOLUMNORDERARRAY = LVM_FIRST + 58

<DllImport("user32.dll", EntryPoint:="SendMessageA")> _
Private Shared Function ListViewColumnOrder(ByVal hwnd As Integer,
ByVal Msg As
Integer, ByVal wParam As Integer, ByRef lParam As Integer) As Integer
End Function


'Sub to change order of columns

Public Sub SetColumnOrder(ByVal ListViewToReorder As ListView, ByVal
SortOrder As Integer())
If SortOrder.Length < 1 Then Exit Sub
If SortOrder.Length > ListViewToReorder.Columns.Count Then Exit
Sub
Dim liSetColumnOrderArray As Integer = LVM_SETCOLUMNORDERARRAY
Dim liSuccess As Integer
liSuccess = ListViewColumnOrder(ListView1.Handle.ToInt32,
liSetColumnOrderArray, SortOrder.Length, SortOrder(0))
If Not liSuccess.Equals(0) Then
ListView1.Refresh()
End If
End Sub


'Code to call sub - pass desired order of columns in an array
Dim sortorder() As Integer
ReDim sortorder(ListView1.Columns.Count - 1)
sortorder(0) = 2 'assumes 3 columns
sortorder(1) = 1
sortorder(2) = 0
SetColumnOrder(ListView1, sortorder)


Below is a sample that illustrates how this could be done. It uses a
Windows
Application project with a ListView and a Commnad button added.

Imports System.Runtime.InteropServices
Public Class Form1
Inherits System.Windows.Forms.Form

Const LVM_FIRST As Integer = &H1000
Const LVM_SETCOLUMNORDERARRAY = LVM_FIRST + 58

<DllImport("user32.dll", EntryPoint:="SendMessageA")> _
Private Shared Function ListViewColumnOrder(ByVal hwnd As Integer,
ByVal Msg As
Integer, ByVal wParam As Integer, ByRef lParam As Integer) As Integer
End Function

Dim FirstTime As Boolean = True
Dim arrData(2, 2) As String


Windows Form Designer generated code

Private Sub Form1_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load

'Fill the array with some data
arrData(0, 0) = "Charlotte"
arrData(0, 1) = "NC"
arrData(0, 2) = "(980) 555-5555"
arrData(1, 0) = "Dallas"
arrData(1, 1) = "TX"
arrData(1, 2) = "(917) 333-3333"
arrData(2, 0) = "Redmond"
arrData(2, 1) = "WA"
arrData(2, 2) = "(425) 888-8888"

SetupListView()

End Sub

Sub SetupListView()
Dim lv As ListView = ListView1
Dim lvitem As ListViewItem
Dim i As Long
Dim ch As ColumnHeader
Dim lvsitem As ListViewItem.ListViewSubItem
Dim lvsitem2 As ListViewItem.ListViewSubItem
Dim intLVItemCounter As Integer
Dim intSubItemCounter As Integer

'Clear the Listview, enable GridLines and FullRowSelect
lv.Clear()
lv.GridLines = True
lv.FullRowSelect = True
lv.View = View.Details
Dim imageListSmall As New ImageList()

For intLVItemCounter = 0 To arrData.GetUpperBound(0)
'Create a new ListViewItem, and set its Text to
'the appropriate value from the array
lvitem = New ListViewItem()
lvitem.Text = arrData(intLVItemCounter, 0)

'Loop through the array elements of the first dimension
'to create SubItems.
For intSubItemCounter = 1 To arrData.GetUpperBound(1)
'Add a SubItem with the text from the appropriate location
in the
array
lvitem.SubItems.Add(arrData(intLVItemCounter,
intSubItemCounter))
Next

'Add the ListViewItem to the control
lv.Items.Add(lvitem)

Next

'Setup imagelist
imageListSmall.Images.Add(Bitmap.FromFile("C:\Program
Files\Microsoft
Visual Studio .NET\Common7\Graphics\icons\Traffic\trffc05.ico"))
imageListSmall.Images.Add(Bitmap.FromFile("C:\Program
Files\Microsoft
Visual Studio .NET\Common7\Graphics\icons\Traffic\trffc06.ico"))
imageListSmall.Images.Add(Bitmap.FromFile("C:\Program
Files\Microsoft
Visual Studio .NET\Common7\Graphics\icons\Traffic\trffc07.ico"))
lv.SmallImageList = imageListSmall

For i = 0 To lv.Items.Count - 1
lv.Items(i).ImageIndex = i
Next i

'Add columns to the control
AddColumns("City")
AddColumns("State")
AddColumns("Telephone")

For Each ch In lv.Columns
ch.Width = -2
Next

End Sub

Sub AddColumns(ByVal Text As String)
Dim lv As ListView = ListView1
Dim ch As ColumnHeader
ch = New ColumnHeader()
ch.Text = Text
lv.Columns.Add(ch)
End Sub


Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click

Static c As Integer
ListView1.AllowColumnReorder = True
ListView1.LabelEdit = True
Dim sortorder() As Integer
ReDim sortorder(ListView1.Columns.Count - 1)
If FirstTime Then
c = 2
FirstTime = False
End If
If c > 2 Then c = 0
sortorder(0) = c
c += 1
If c > 2 Then c = 0
sortorder(1) = c
c += 1
If c > 2 Then c = 0
sortorder(2) = c

SetColumnOrder(ListView1, sortorder)

End Sub


Public Sub SetColumnOrder(ByVal ListViewToReorder As ListView, ByVal
SortOrder
As Integer())
If SortOrder.Length < 1 Then Exit Sub
If SortOrder.Length > ListViewToReorder.Columns.Count Then Exit Sub
Dim liSetColumnOrderArray As Integer = LVM_SETCOLUMNORDERARRAY
Dim liSuccess As Integer
liSuccess = ListViewColumnOrder(ListView1.Handle.ToInt32,
liSetColumnOrderArray, SortOrder.Length, SortOrder(0))
If Not liSuccess.Equals(0) Then
ListView1.Refresh()
End If
End Sub




End Class
 
V

VR

Thanks for your help. It works flawlessly.

VR
-----Original Message-----
Hi,

Sending the lvm_setcolumnorderarray message to the listview along with
an array that specifies the left to right order of the columns will allow
you to
programatically change the order of the columns in the listview. The
ListView view
should be set to Details

Here is VB.NET code. I think you can easily convert it to C#.

'Sendmessage declare
Const LVM_FIRST As Integer = &H1000
Const LVM_SETCOLUMNORDERARRAY = LVM_FIRST + 58

<DllImport("user32.dll", EntryPoint:="SendMessageA")> _
Private Shared Function ListViewColumnOrder(ByVal hwnd As Integer,
ByVal Msg As
Integer, ByVal wParam As Integer, ByRef lParam As Integer) As Integer
End Function


'Sub to change order of columns

Public Sub SetColumnOrder(ByVal ListViewToReorder As ListView, ByVal
SortOrder As Integer())
If SortOrder.Length < 1 Then Exit Sub
If SortOrder.Length >
ListViewToReorder.Columns.Count Then Exit
Sub
Dim liSetColumnOrderArray As Integer = LVM_SETCOLUMNORDERARRAY
Dim liSuccess As Integer
liSuccess = ListViewColumnOrder (ListView1.Handle.ToInt32,
liSetColumnOrderArray, SortOrder.Length, SortOrder(0))
If Not liSuccess.Equals(0) Then
ListView1.Refresh()
End If
End Sub


'Code to call sub - pass desired order of columns in an array
Dim sortorder() As Integer
ReDim sortorder(ListView1.Columns.Count - 1)
sortorder(0) = 2 'assumes 3 columns
sortorder(1) = 1
sortorder(2) = 0
SetColumnOrder(ListView1, sortorder)


Below is a sample that illustrates how this could be done. It uses a
Windows
Application project with a ListView and a Commnad button added.

Imports System.Runtime.InteropServices
Public Class Form1
Inherits System.Windows.Forms.Form

Const LVM_FIRST As Integer = &H1000
Const LVM_SETCOLUMNORDERARRAY = LVM_FIRST + 58

<DllImport("user32.dll", EntryPoint:="SendMessageA")> _
Private Shared Function ListViewColumnOrder(ByVal hwnd As Integer,
ByVal Msg As
Integer, ByVal wParam As Integer, ByRef lParam As Integer) As Integer
End Function

Dim FirstTime As Boolean = True
Dim arrData(2, 2) As String


Windows Form Designer generated code

Private Sub Form1_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load

'Fill the array with some data
arrData(0, 0) = "Charlotte"
arrData(0, 1) = "NC"
arrData(0, 2) = "(980) 555-5555"
arrData(1, 0) = "Dallas"
arrData(1, 1) = "TX"
arrData(1, 2) = "(917) 333-3333"
arrData(2, 0) = "Redmond"
arrData(2, 1) = "WA"
arrData(2, 2) = "(425) 888-8888"

SetupListView()

End Sub

Sub SetupListView()
Dim lv As ListView = ListView1
Dim lvitem As ListViewItem
Dim i As Long
Dim ch As ColumnHeader
Dim lvsitem As ListViewItem.ListViewSubItem
Dim lvsitem2 As ListViewItem.ListViewSubItem
Dim intLVItemCounter As Integer
Dim intSubItemCounter As Integer

'Clear the Listview, enable GridLines and FullRowSelect
lv.Clear()
lv.GridLines = True
lv.FullRowSelect = True
lv.View = View.Details
Dim imageListSmall As New ImageList()

For intLVItemCounter = 0 To arrData.GetUpperBound (0)
'Create a new ListViewItem, and set its Text to
'the appropriate value from the array
lvitem = New ListViewItem()
lvitem.Text = arrData(intLVItemCounter, 0)

'Loop through the array elements of the first dimension
'to create SubItems.
For intSubItemCounter = 1 To arrData.GetUpperBound(1)
'Add a SubItem with the text from the appropriate location
in the
array
lvitem.SubItems.Add(arrData (intLVItemCounter,
intSubItemCounter))
Next

'Add the ListViewItem to the control
lv.Items.Add(lvitem)

Next

'Setup imagelist
imageListSmall.Images.Add(Bitmap.FromFile ("C:\Program
Files\Microsoft
Visual Studio .NET\Common7 \Graphics\icons\Traffic\trffc05.ico"))
("C:\Program
Files\Microsoft
Visual Studio .NET\Common7 \Graphics\icons\Traffic\trffc06.ico"))
("C:\Program
Files\Microsoft
Visual Studio .NET\Common7 \Graphics\icons\Traffic\trffc07.ico"))
lv.SmallImageList = imageListSmall

For i = 0 To lv.Items.Count - 1
lv.Items(i).ImageIndex = i
Next i

'Add columns to the control
AddColumns("City")
AddColumns("State")
AddColumns("Telephone")

For Each ch In lv.Columns
ch.Width = -2
Next

End Sub

Sub AddColumns(ByVal Text As String)
Dim lv As ListView = ListView1
Dim ch As ColumnHeader
ch = New ColumnHeader()
ch.Text = Text
lv.Columns.Add(ch)
End Sub


Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click

Static c As Integer
ListView1.AllowColumnReorder = True
ListView1.LabelEdit = True
Dim sortorder() As Integer
ReDim sortorder(ListView1.Columns.Count - 1)
If FirstTime Then
c = 2
FirstTime = False
End If
If c > 2 Then c = 0
sortorder(0) = c
c += 1
If c > 2 Then c = 0
sortorder(1) = c
c += 1
If c > 2 Then c = 0
sortorder(2) = c

SetColumnOrder(ListView1, sortorder)

End Sub


Public Sub SetColumnOrder(ByVal ListViewToReorder As ListView, ByVal
SortOrder
As Integer())
If SortOrder.Length < 1 Then Exit Sub
If SortOrder.Length >
ListViewToReorder.Columns.Count Then Exit Sub
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top