Jak wyświetlić strzałkę sortowania w nagłówku posortowanej kolumny w widoku listy, który jest zgodny z natywnym wyglądem systemu operacyjnego?Jak wyświetlić strzałkę sortowania w nagłówku kolumny widoku listy przy użyciu C#?
35
A
Odpowiedz
63
można wykorzystywać następujące metody rozszerzenie ustawić strzałkę sortowania do konkretnej kolumny:
[EditorBrowsable(EditorBrowsableState.Never)]
public static class ListViewExtensions
{
[StructLayout(LayoutKind.Sequential)]
public struct HDITEM
{
public Mask mask;
public int cxy;
[MarshalAs(UnmanagedType.LPTStr)] public string pszText;
public IntPtr hbm;
public int cchTextMax;
public Format fmt;
public IntPtr lParam;
// _WIN32_IE >= 0x0300
public int iImage;
public int iOrder;
// _WIN32_IE >= 0x0500
public uint type;
public IntPtr pvFilter;
// _WIN32_WINNT >= 0x0600
public uint state;
[Flags]
public enum Mask
{
Format = 0x4, // HDI_FORMAT
};
[Flags]
public enum Format
{
SortDown = 0x200, // HDF_SORTDOWN
SortUp = 0x400, // HDF_SORTUP
};
};
public const int LVM_FIRST = 0x1000;
public const int LVM_GETHEADER = LVM_FIRST + 31;
public const int HDM_FIRST = 0x1200;
public const int HDM_GETITEM = HDM_FIRST + 11;
public const int HDM_SETITEM = HDM_FIRST + 12;
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr SendMessage(IntPtr hWnd, UInt32 msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr SendMessage(IntPtr hWnd, UInt32 msg, IntPtr wParam, ref HDITEM lParam);
public static void SetSortIcon(this ListView listViewControl, int columnIndex, SortOrder order)
{
IntPtr columnHeader = SendMessage(listViewControl.Handle, LVM_GETHEADER, IntPtr.Zero, IntPtr.Zero);
for (int columnNumber = 0; columnNumber <= listViewControl.Columns.Count - 1; columnNumber++)
{
var columnPtr = new IntPtr(columnNumber);
var item = new HDITEM
{
mask = HDITEM.Mask.Format
};
if (SendMessage(columnHeader, HDM_GETITEM, columnPtr, ref item) == IntPtr.Zero)
{
throw new Win32Exception();
}
if (order != SortOrder.None && columnNumber == columnIndex)
{
switch (order)
{
case SortOrder.Ascending:
item.fmt &= ~HDITEM.Format.SortDown;
item.fmt |= HDITEM.Format.SortUp;
break;
case SortOrder.Descending:
item.fmt &= ~HDITEM.Format.SortUp;
item.fmt |= HDITEM.Format.SortDown;
break;
}
}
else
{
item.fmt &= ~HDITEM.Format.SortDown & ~HDITEM.Format.SortUp;
}
if (SendMessage(columnHeader, HDM_SETITEM, columnPtr, ref item) == IntPtr.Zero)
{
throw new Win32Exception();
}
}
}
}
Następnie można wywołać metodę rozszerzenia jak takie:
myListView.SetSortIcon(0, SortOrder.Ascending);
To działa przy użyciu P/Wywołaj do:
- Uzyskaj uchwyt kontrolki nagłówka dla widoku listy przy użyciu LVM_GETHEADER m eessage.
- Uzyskaj informacje o kolumnie nagłówkowej, używając wiadomości HDM_GETITEM.
- Następnie modyfikuje
fmt
, aby ustawić/wyczyścić flagiHDF_SORTDOWN
iHDF_SORTUP
na zwróconej strukturze HDITEM. - W końcu ponownie ustawia informacje z wiadomości HDM_SETITEM.
To jak to wygląda:
4
Świetna odpowiedź przez Andrzeja. Jeśli ktoś szuka odpowiednik VB.net tutaj jest:
Public Module ListViewExtensions
Public Enum SortOrder
None
Ascending
Descending
End Enum
<StructLayout(LayoutKind.Sequential)>
Public Structure HDITEM
Public theMask As Mask
Public cxy As Integer
<MarshalAs(UnmanagedType.LPTStr)>
Public pszText As String
Public hbm As IntPtr
Public cchTextMax As Integer
Public fmt As Format
Public lParam As IntPtr
' _WIN32_IE >= 0x0300
Public iImage As Integer
Public iOrder As Integer
' _WIN32_IE >= 0x0500
Public type As UInteger
Public pvFilter As IntPtr
' _WIN32_WINNT >= 0x0600
Public state As UInteger
<Flags()>
Public Enum Mask
Format = &H4 ' HDI_FORMAT
End Enum
<Flags()>
Public Enum Format
SortDown = &H200 ' HDF_SORTDOWN
SortUp = &H400 ' HDF_SORTUP
End Enum
End Structure
Public Const LVM_FIRST As Integer = &H1000
Public Const LVM_GETHEADER As Integer = LVM_FIRST + 31
Public Const HDM_FIRST As Integer = &H1200
Public Const HDM_GETITEM As Integer = HDM_FIRST + 11
Public Const HDM_SETITEM As Integer = HDM_FIRST + 12
<DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True)>
Public Function SendMessage(hWnd As IntPtr, msg As UInt32, wParam As IntPtr, lParam As IntPtr) As IntPtr
End Function
<DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True)>
Public Function SendMessage(hWnd As IntPtr, msg As UInt32, wParam As IntPtr, ByRef lParam As HDITEM) As IntPtr
End Function
<Extension()>
Public Sub SetSortIcon(listViewControl As ListView, columnIndex As Integer, order As SortOrder)
Dim columnHeader As IntPtr = SendMessage(listViewControl.Handle, LVM_GETHEADER, IntPtr.Zero, IntPtr.Zero)
For columnNumber As Integer = 0 To listViewControl.Columns.Count - 1
Dim columnPtr As New IntPtr(columnNumber)
Dim item As New HDITEM
item.theMask = HDITEM.Mask.Format
If SendMessage(columnHeader, HDM_GETITEM, columnPtr, item) = IntPtr.Zero Then Throw New Win32Exception
If order <> SortOrder.None AndAlso columnNumber = columnIndex Then
Select Case order
Case SortOrder.Ascending
item.fmt = item.fmt And Not HDITEM.Format.SortDown
item.fmt = item.fmt Or HDITEM.Format.SortUp
Case SortOrder.Descending
item.fmt = item.fmt And Not HDITEM.Format.SortUp
item.fmt = item.fmt Or HDITEM.Format.SortDown
End Select
Else
item.fmt = item.fmt And Not HDITEM.Format.SortDown And Not HDITEM.Format.SortUp
End If
If SendMessage(columnHeader, HDM_SETITEM, columnPtr, item) = IntPtr.Zero Then Throw New Win32Exception
Next
End Sub
End Module
1
Dla innych leniwy C++ (jak ja):
// possible sorting header icons/indicators
enum class ListViewSortArrow { None, Ascending, Descending };
BOOL LVHeader_SetSortArrow(HWND hHeader, int nColumn, ListViewSortArrow sortArrow)
{
ASSERT(hHeader);
HDITEM hdrItem = { 0 };
hdrItem.mask = HDI_FORMAT;
if (Header_GetItem(hHeader, nColumn, &hdrItem))
{
switch (sortArrow)
{
default:
ASSERT(false);
case ListViewSortArrow::None:
hdrItem.fmt = hdrItem.fmt & ~(HDF_SORTDOWN | HDF_SORTUP);
break;
case ListViewSortArrow::Ascending:
hdrItem.fmt = (hdrItem.fmt & ~HDF_SORTDOWN) | HDF_SORTUP;
break;
case ListViewSortArrow::Descending:
hdrItem.fmt = (hdrItem.fmt & ~HDF_SORTUP) | HDF_SORTDOWN;
break;
}
return Header_SetItem(hHeader, nColumn, &hdrItem);
}
return FALSE;
}
BOOL ListView_SetSortArrow(HWND hListView, int nColumn, ListViewSortArrow sortArrow)
{
ASSERT(hListView);
if (HWND hHeader = ListView_GetHeader(hListView))
return LVHeader_SetSortArrow(hHeader, nColumn, sortArrow);
return FALSE;
}
Powiązane problemy
- 1. Jak wyświetlić strzałkę sortowania w kolumnie TListView?
- 2. Jak wyświetlić console.log() w aplikacji przy użyciu widoku jonowego
- 3. sortowania listy listy w python
- 4. jak wyświetlić okno alertu po pomyślnym wstawieniu przy użyciu C#
- 5. kolumny sortowania w Matlab
- 6. sortowania std :: list przy użyciu std :: sort
- 7. Znajdź wartość z widoku danych przy użyciu nazwy kolumny
- 8. sposób sortowania kolekcji przy DateTime w C#
- 9. wyświetlania pojedynczej kolumny w widoku listy z dwiema grupami
- 10. Wypełnianie JTable przy użyciu listy
- 11. losowe wartości przy użyciu scalania w seryjnej sortowania C++
- 12. Jak narysować tekst w niestandardowym widoku przy użyciu Objective-C?
- 13. Nie można wyświetlić widoku przy użyciu urządzenia Butterknife 8.1.0
- 14. C# sortowania tabeli przez 2 kolumny
- 15. Jak wyświetlić wielowiersz z listy tablic w jednym widoku tekstowym?
- 16. Jak wyświetlić ostatnio dodany element widoku listy w WPF ListView
- 17. Jak wyświetlić trzy kolumny w rzędzie?
- 18. Android: nie można odświeżyć widoku listy przy użyciu CustomAdaptera
- 19. Sortowanie tabeli Sql przy użyciu kolumny alias
- 20. Potrzebuję pomocy, aby uzyskać normalnie wyglądającą strzałkę w dół Unicode w UILabel w ten sposób ⬇
- 21. Jak wyświetlić obraz RGB przy użyciu pylab
- 22. Jak zaimplementować funkcję sortowania w widoku siatki?
- 23. Porządek sortowania przy użyciu foreach w tablicy, liście itp.
- 24. Jak wyświetlić ProgressDialog przy użyciu fragmentu
- 25. Kontrola hiperłącza przy użyciu pola listy w C#
- 26. Zapytanie arkusza kalkulacyjnego Google: jak zamienić tekst w nagłówku kolumny?
- 27. C# - Aktualizacja subitem w widoku listy
- 28. Jak zwiększyć rozmiar widoku w widoku listy?
- 29. Formatowanie kolumny widoku listy WPF, aby wyświetlić tylko 2 punkty dziesiętne.
- 30. Jak uzyskać liczbę wierszy przy użyciu SqlDataReader w C#
Zauważ, że Application.EnableVisualStyles(); musi być wywołany, aby powyższy kod zadziałał. – Rune
Nie, nie ma. Działa również w przypadku nielistylonych listView. –
Podana wartość LVCOLUMN to w rzeczywistości HDITEM. Zdaję sobie sprawę, skoro sam to określasz, że to nie ma znaczenia, ale tłumacząc to na C++, pomyliłem mnie na kilka :). – Bob