Title: Display icons next to ListView sub-items in C#
This example displays icons next to ListView sub-items when the ListView is in Detail View. This requires two steps beyond what is required to make a ListView display item icons: (1) assigning image indices to the sub-items, and (2) making the ListView sub-items display them.
Both of these tasks require using the SendMessage API function. The example uses the following code to declare the API functions and constants that it needs.
[DllImport("user32.dll")]
private static extern int SendMessage(IntPtr hWnd, uint Msg,
int wParam, int lParam);
[DllImport("user32.dll")]
private static extern int SendMessage(IntPtr hWnd, uint Msg,
int wParam, ref LV_ITEM item_info);
private struct LV_ITEM
{
public UInt32 uiMask;
public Int32 iItem;
public Int32 iSubItem;
public UInt32 uiState;
public UInt32 uiStateMask;
public string pszText;
public Int32 cchTextMax;
public Int32 iImage;
public IntPtr lParam;
};
public const Int32 LVM_FIRST = 0x1000;
public const Int32 LVM_SETITEM = LVM_FIRST + 6;
public const Int32 LVIF_IMAGE = 0x2;
public const int LVW_FIRST = 0x1000;
public const int LVM_SETEXTENDEDLISTVIEWSTYLE = LVW_FIRST + 54;
public const int LVM_GETEXTENDEDLISTVIEWSTYLE = LVW_FIRST + 55;
public const int LVS_EX_SUBITEMIMAGES = 0x2;
This code defines two versions of the SendMessage function, one that takes an integer as its final parameter and another that takes a reference to an LV_ITEM structure as its final parameter.
The code then defines the LV_ITEM structure. This structure contains fields that define the characteristics of a ListView item.
The rest of the code defines some constants that are needed to display icons in ListView sub-items.
The following ListView extension method adds an icon to a sub-item.
// Add an icon to a subitem.
public static void AddIconToSubitem(this ListView lvw,
int row, int col, int icon_num)
{
LV_ITEM lvi = new LV_ITEM();
lvi.iItem = row; // Row.
lvi.iSubItem = col; // Column.
lvi.uiMask = LVIF_IMAGE; // We're setting the image.
lvi.iImage = icon_num; // The image index in the ImageList.
// Send the LVM_SETITEM message.
SendMessage(lvw.Handle, LVM_SETITEM, 0, ref lvi);
}
This method takes as parameters the row and column of the sub-item and the index of its icon in the ListView control's SmallImageList. (Note that the main item is in column 0, so you don't need to use this method to set that item's image index.)
The code creates a LV_ITEM structure and sets its row and column. It sets the uiMask value to LVIF_IMAGE to indicate that the code is setting icons for ListView sub-items. The code then sets the iImage value to the image's index. It finishes by calling SendMessage to send the ListView control the LVM_SETITEM message.
The following code shows how the program turns the sub-item icons on and off.
// Make the ListView display sub-item icons.
public static void ShowSubItemIcons(this ListView lvw, bool show)
{
// Get the current style.
int style = SendMessage(lvw.Handle,
LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0);
// Show or hide sub-item icons.
if (show) style |= LVS_EX_SUBITEMIMAGES;
else style &= (~LVS_EX_SUBITEMIMAGES);
SendMessage(lvw.Handle,
LVM_SETEXTENDEDLISTVIEWSTYLE, 0, style);
}
The code first calls SendMessage to send the LVM_GETEXTENDEDLISTVIEWSTYLE message to the ListView control. The result is an integer that represents the control's current style.
Depending on whether the program's Sub-item Icons check box is checked, the code sets or clears the LVS_EX_SUBITEMIMAGES style bit, which determines whether the control displays icons in the ListView sub-items.
Finally, the code calls SendMessage again, this time with the LVM_SETEXTENDEDLISTVIEWSTYLE message, to make the ListView use the new style.
Download the example to experiment with it and to see additional details.
|