Microsoft KB Archive/316202

= PRB: Cannot Assign Images to a ColumnHeader Control in a Windows Forms ListView Control Using Visual Basic .NET =

Article ID: 316202

Article Last Modified on 2/22/2007

-

APPLIES TO


 * Microsoft .NET Framework 1.1
 * Microsoft .NET Framework 1.0
 * Microsoft Visual Basic .NET 2003 Standard Edition
 * Microsoft Visual Basic .NET 2002 Standard Edition

-



This article was previously published under Q316202



For a Microsoft Visual C# .NET version of this article, see 314933.



SYMPTOMS
When you attempt to assign images to a ColumnHeader control in a Windows Forms ListView control, the operation is unsuccessful.



CAUSE
This behavior occurs because the .NET implementation of the System.Windows.Forms.ColumnHeader class does not allow you to assign an image to the ColumnHeader control. You can assign only text to a ColumnHeader control.



RESOLUTION
To work around this issue in a .NET Windows Forms application, use Interop Services to send messages to the underlying Win32 ListView control to direct it to add the images to specific columns.



MORE INFORMATION
A ColumnHeader control is an item in a Windows Forms ListView control that contains heading text. You can use the Add method of the ListView.ColumnHeaderCollection class to add ColumnHeader objects to a ListView control. Because this class does not accommodate images, you can use Interop Services in a .NET Windows Forms application to add the images.

The following code sample demonstrates how to:
 * Send an LVM_GETHEADER message to the Windows Forms ListView control to obtain the ColumnHeader object.
 * Send an HDM_SETIMAGELIST message to the ColumnHeader control to set the image list that you want.
 * Fill out an LVCOLUMN structure and send it to the ListView control through an LVM_SETCOLUMN message to add an image from the image list to one of the columns.

Step-by-Step Example
 Start Microsoft Visual Studio .NET, and then create a new Windows Application in Visual Basic .NET. Form1 is added to the project by default. On Form1, add a ListView control, a Button control, and an ImageList control.

Their default names are ListView1, Button1, and ImageList1 respectively. In the properties of ImageList1, click the ellipsis button (...) of the Images property, and then add two images to the control.  In the code window of Form1.vb, add the following statement at the very top so that it is the first line of code: Imports System.Runtime.InteropServices   In the Form1 class, after the Inherits statement, copy and paste the following code: Public Const LVM_GETHEADER = 4127 Public Const HDM_SETIMAGELIST = 4616 Public Const LVM_SETCOLUMN = 4122 Public Const LVCF_FMT = 1 Public Const LVCF_IMAGE = 16 Public Const LVCFMT_IMAGE = 2048

'Define the LVCOLUMN for use with Interop. <StructLayout(LayoutKind.Sequential, pack:=8, CharSet:=CharSet.Auto)> _ Structure LVCOLUMN Dim mask As Integer Dim fmt As Integer Dim cx As Integer Dim pszText As IntPtr Dim cchTextMax As Integer Dim iSubItem As Integer Dim iImage As Integer Dim iOrder As Integer End Structure

'Declare two overloaded SendMessage functions. The 'difference is in the last parameter. <DllImport(&quot;User32.dll&quot;)> _ Public Overloads Shared Function SendMessage _ (ByVal hWnd As IntPtr, ByVal Msg As Integer, _    ByVal wParam As Integer, ByVal lParam As Integer) As IntPtr End Function

<DllImport(&quot;User32&quot;, CharSet:=CharSet.Auto)> _ Public Overloads Shared Function SendMessage _ (ByVal hWnd As IntPtr, ByVal msg As Integer, _    ByVal wParam As Integer, ByRef lParam As LVCOLUMN) As IntPtr End Function </li>  In the Form1_Load event, copy and paste the following code: ListView1.View = View.Details ListView1.Columns.Add(&quot;Column 0&quot;, 60, HorizontalAlignment.Left) ListView1.Columns.Add(&quot;Column 1&quot;, 60, HorizontalAlignment.Left) </li>  In the Button1_Click event, copy and paste the following code: Dim hwnd As IntPtr Dim lret As IntPtr Dim i As Integer

'Assign the ImageList to the header control. 'The header control includes all columns. 'Get a handle to the header control. hwnd = SendMessage(ListView1.Handle, LVM_GETHEADER, 0, 0)

'Add the ImageList to the header control. lret = SendMessage(hwnd, HDM_SETIMAGELIST, 0, (ImageList1.Handle).ToInt32)

'The code to follow uses successive images in the ImageList to loop 'through all columns and place successive columns in the ColumnHeader. 'This code uses LVCOLUMN to define alignment. By using LVCOLUMN here, 'you reset the alignment if it was defined in the designer. 'If you need to set the alignment, you must change the code below to set it here. For i = 0 To ListView1.Columns.Count - 1 'Use the LVM_SETCOLUMN message to set the column's image index. Dim col As LVCOLUMN

col.mask = LVCF_FMT Or LVCF_IMAGE col.fmt = LVCFMT_IMAGE 'The image to use from the Image List. col.iImage = i     col.cchTextMax = 0 col.cx = 0 col.iOrder = 0 col.iSubItem = 0 col.pszText = IntPtr.op_Explicit(0) 'Send the LVM_SETCOLUMN message. 'The column to which you are assigning the image is defined in the third parameter. lret = SendMessage(ListView1.Handle, LVM_SETCOLUMN, i, col) Next </li> Press the F5 key to run the application. Click Button1, and notice that an image is added to each column header.</li></ol>

Keywords: kbwindowsforms kblistview kbctrl kbprb KB316202

-

[mailto:TECHNET@MICROSOFT.COM Send feedback to Microsoft]

© Microsoft Corporation. All rights reserved.