Этот метод эмулирует стиль выделения «Windows XP». Vista и Win7 используют расширенную функциональность ListViews, которой нет (пока?) В .NET. При необходимости это можно сделать с помощью Interop.
Вот как это сделать:
Создайте ImageList, который содержит следующие изображения: 0: пусто, 1: «вверх» и 2: «вниз»
- Назначьте этот ImageList для вашего свойства ListView.SmallImageList
- Каждый раз, когда вы добавляете элемент в ListView, убедитесь, что его UseItemStyleForSubItems имеет значение «false»
- Добавьте код сортировки в ваше приложение, описание которого здесь
В коде, который вы только что добавили, замените обработчик ColumnClick следующим кодом (экземпляр ListView здесь называется "_List"):
void _List_ColumnClick (отправитель объекта, ColumnClickEventArgs e) {
_List.SuspendLayout ();
if (e.Column == lvwColumnSorter.SortColumn) {// ранее отсортированный столбец будет перевернут
if (lvwColumnSorter.Order == SortOrder.Ascending) {
lvwColumnSorter.Order = SortOrder.Descending;
} еще {
lvwColumnSorter.Order = SortOrder.Ascending;
}
} else {// новый столбец будет отсортирован
_List.Columns [lvwColumnSorter.SortColumn] .ImageIndex = 0;
foreach (ListViewItem lvi в _List.Items) {
lvi.SubItems [lvwColumnSorter.SortColumn] .BackColor = SystemColors.Window;
}
lvwColumnSorter.SortColumn = e.Column;
lvwColumnSorter.Order = SortOrder.Ascending;
}
_List.Sort ();
_List.Columns [e.Column] .ImageIndex = lvwColumnSorter.Order == SortOrder.Ascending? 1: 2;
foreach (ListViewItem lvi в _List.Items) {
lvi.SubItems [e.Column] .BackColor = SystemColors.Info; // это цвет, используемый для отслеживания
}
_List.ResumeLayout ();
}
Edit:
Ниже приведен подход взаимодействия:
[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, uint message, UIntPtr wParam, IntPtr lParam);
[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, uint message, UIntPtr wParam, ref HDITEM lParam);
public enum WM {
LVM_FIRST = 0x1000, // ListView messages
// ...
LVM_GETHEADER = LVM_FIRST + 31,
// ...
HDM_FIRST = 0x1200, // Header messages
// ...
HDM_SETITEM = HDM_FIRST + 12,
// ...
HDM_SETFOCUSEDITEM = HDM_FIRST + 28,
}
public enum HDI {
HDI_WIDTH = 0x0001,
HDI_HEIGHT = HDI_WIDTH,
HDI_TEXT = 0x0002,
HDI_FORMAT = 0x0004,
HDI_LPARAM = 0x0008,
HDI_BITMAP = 0x0010,
HDI_IMAGE = 0x0020,
HDI_DI_SETITEM = 0x0040,
HDI_ORDER = 0x0080,
HDI_FILTER = 0x0100,
HDI_STATE = 0x0200
}
public enum HDF {
HDF_LEFT = 0x0000,
HDF_RIGHT = 0x0001,
HDF_CENTER = 0x0002,
HDF_JUSTIFYMASK = 0x0003,
HDF_RTLREADING = 0x0004,
HDF_BITMAP = 0x2000,
HDF_STRING = 0x4000,
HDF_OWNERDRAW = 0x8000,
HDF_IMAGE = 0x0800,
HDF_BITMAP_ON_RIGHT = 0x1000,
HDF_SORTUP = 0x0400,
HDF_SORTDOWN = 0x0200,
HDF_CHECKBOX = 0x0040,
HDF_CHECKED = 0x0080,
HDF_FIXEDWIDTH = 0x0100,
HDF_SPLITBUTTON = 0x1000000
}
[StructLayout(LayoutKind.Sequential)]
public struct HDITEM {
public uint mask;
public int cxy;
public String pszText;
public IntPtr hbm;
public int cchTextMax;
public int fmt;
public IntPtr lParam;
public int iImage;
public int iOrder;
public uint type;
public IntPtr pvFilter; // this is void*
public uint state;
}
void _List_ColumnClick(object sender, ColumnClickEventArgs e) {
_List.SuspendLayout();
HDITEM hdi = new HDITEM();
hdi.mask = (uint)HDI.HDI_FORMAT;
hdi.fmt = (int)HDF.HDF_STRING;
IntPtr hHeader = (IntPtr)SendMessage(_List.Handle, (uint)WM.LVM_GETHEADER, (UIntPtr)0, (IntPtr)0);
if (e.Column == lvwColumnSorter.SortColumn) { // the column previously sorted will be flipped
if (lvwColumnSorter.Order == SortOrder.Ascending) {
lvwColumnSorter.Order = SortOrder.Descending;
} else {
lvwColumnSorter.Order = SortOrder.Ascending;
}
} else { // new column will be sorted
SendMessage((IntPtr)hHeader, (uint)WM.HDM_SETITEM, (UIntPtr)lvwColumnSorter.SortColumn, ref hdi);
foreach (ListViewItem lvi in _List.Items) {
lvi.SubItems[lvwColumnSorter.SortColumn].BackColor = SystemColors.Window;
}
lvwColumnSorter.SortColumn = e.Column;
lvwColumnSorter.Order = SortOrder.Ascending;
}
_List.Sort();
hdi.fmt |= (lvwColumnSorter.Order == SortOrder.Ascending ? (int)HDF.HDF_SORTDOWN : (int)HDF.HDF_SORTUP);
SendMessage((IntPtr)hHeader, (uint)WM.HDM_SETITEM, (UIntPtr)e.Column, ref hdi);
foreach (ListViewItem lvi in _List.Items) {
lvi.SubItems[e.Column].BackColor = SystemColors.Info; // this is the color used for tracking
}
_List.ResumeLayout();
}