Benutzer mit den meisten Antworten
listview columnheader systemarrow nach setzen wieder entfernen?

Frage
-
Oh, ist mir ja schon peinlich! Schlage mich immer noch mit einer akzeptablen Lösung für meine Sort-Pfeile herum.
Also, ich bin nun am Probieren mit den Windows-Systemarrows, so eine Darstellung zum sortieren wie beim Explorer.
Ich verwende den code von rapidleach bzw OsuDevice.Pfeil setzen klappt ja gut, auch die listitems sind nun nicht mehr irgendwie eingerückt. Aber ihn wieder zu entfernen klappt nun nicht.
Friend Sub SetColumnHeaderImage(ByVal lvw As ListView, ByVal Column As Integer, _ ByVal ImageAlignment As HorizontalImageAlignment, ByVal ImageIndex As Integer, _ ByVal UseWinArrows As Boolean, Optional ByVal imgList As ImageList = Nothing, _ Optional ByVal WinArrow As WindowsArrow = Nothing) Dim hwnd As IntPtr Dim lret As IntPtr If UseWinArrows Then 'The header control includes all columns. 'Get a handle to the header control. hwnd = SendMessage(lvw.Handle, LVM_GETHEADER, 0, 0) 'When using the Windows Arrows there is no need to add imagelist to the header control. Dim col As LVCOLUMN col.mask = LVCF_FMT col.fmt = WinArrow col.iImage = -1 col.cchTextMax = 0 col.cx = 0 col.iOrder = 0 col.iSubItem = 0 col.pszText = IntPtr.Zero lret = SendMessage(lvw.Handle, LVM_SETCOLUMN, Column, col)
- als winarrow 0 oder nothing zu übergeben nützt nix.
- in col.fmt = WinArrow + ImageAlignment wird Imagealignement nicht berücksichtigt. hab es daher weggelassen.
- die iImage-Eigenschaft wird hier gar nicht ausgewertet. Setzen nützt nix.Habt Ihr hier eine Idee? (Seltsamerweise wird in den Quellen hier gar nicht drauf eingegangen)
Gruß und Dank!
Thomas
Antworten
-
Hallo,
übergebe ein 0 für die Pfeilrichtung (siehe das Enum weiter unten):SetColumnHeaderImage(ListView1, 0, HorizontalImageAlignment.Left, -1, Nothing, WindowsArrow.NOTHING)
Ich habe bei dem Aufruf UseWinArrows weg gelassen, da der Parameter bei deinem (verkürzten) Code unnötig ist.
Hier mein erweitertes Enum:
Public Enum WindowsArrow WIN_ARROW_UP = 1024 WIN_ARROW_DOWN = 512
Da die 0 oftmals der Standard ist habe ich das getestet und es funktionierte. (Unter Windows 8.1 x64 getestet)
NOTHING = 0'Neu hinzugefügt End Enum
Nun noch für alle Anderen, der fehlende Code stammt von hier:
http://social.msdn.microsoft.com/Forums/vstudio/en-US/60200f5a-5612-4322-934a-8016ee99d2b1/how-to-add-remove-listview-columnheader-sort-indicator-win-vista-vb-2008?forum=vbgeneralich%20f%C3%A4nde%20es%20aber%20schade,%20wenKoopakiller [kuːpakɪllɐ] (Tom Lambert)
Webseite |
Code Beispiele |
Facebook |
Twitter |
Snippets
C# ↔ VB.NET Konverter
Markiert bitte beantwortende Posts als Antwort und bewertet Beiträge. Danke.- Als Antwort markiert Migration Sucks Montag, 18. November 2013 15:48
-
Hallo Thomas,
ich habe da etwas aufgeräumt und ergänzt. Vorläufig ist dabei herausgekommen - weitere Tests Deinerseits sind empfehlenswert:
''' <summary>Anzeige der Sortierung im ListView ColumnHeader</summary> Public Enum ColumnHeaderArrow ''' <summary>kein Pfeil.</summary> None = 0 ''' <summary>Pfeil nach oben.</summary> Up = 1 ''' <summary>Pfeil nach unten.</summary> Down = 2 End Enum Public Module ListViewNativeMethods ''' <summary> ''' Setzt oder löscht die Anzeige eines Pfeiles in einer ListView Überschrift ''' </summary> ''' <param name="header">Die Spalte.</param> ''' <param name="order">Die Sortierung.</param> Public Sub SetColumnHeaderArrow(header As ColumnHeader, order As ColumnHeaderArrow) Dim lvw = header.ListView If lvw.IsHandleCreated Then 'Dim hwnd As IntPtr = SendMessage(lvw.Handle, LVM_GETHEADER, 0, 0) Dim column As LVCOLUMN column.mask = LVCF_FMT 'Or LVCF_IMAGE Select Case header.TextAlign Case HorizontalAlignment.Right column.fmt = LVCFMT_RIGHT Case HorizontalAlignment.Center column.fmt = LVCFMT_CENTER Case Else column.fmt = LVCFMT_LEFT End Select If order = ColumnHeaderArrow.Up Then column.fmt = column.fmt Or HDF_SORTUP ElseIf order = ColumnHeaderArrow.Down Then column.fmt = column.fmt Or HDF_SORTDOWN End If column.iImage = 0 SendMessage(lvw.Handle, LVM_SETCOLUMN, header.Index, column) End If End Sub ''' <summary> ''' Liefert die Anzeige eines Pfeiles in einer ListView Überschrift ''' </summary> ''' <param name="header">Die Spalte.</param> ''' <returns>Die Sortierung.</returns> Public Function GetColumnHeaderArrow(header As ColumnHeader) As ColumnHeaderArrow Dim lvw = header.ListView If lvw.IsHandleCreated Then 'Dim hwnd As IntPtr = SendMessage(lvw.Handle, LVM_GETHEADER, 0, 0) Dim column As LVCOLUMN column.mask = LVCF_FMT If SendMessage(lvw.Handle, LVM_GETCOLUMN, header.Index, column) <> IntPtr.Zero Then If (column.fmt And HDF_SORTDOWN) = HDF_SORTDOWN Then Return ColumnHeaderArrow.Down ElseIf (column.fmt And HDF_SORTUP) = HDF_SORTUP Then Return ColumnHeaderArrow.Up End If End If End If Return ColumnHeaderArrow.None End Function Const LVM_GETCOLUMN = 4121 Const LVM_SETCOLUMN = 4122 Const LVM_GETHEADER = 4127 Const LVCF_FMT = 1 Const LVCF_IMAGE = 16 Const LVCFMT_IMAGE = 2048 ' Ausrichtung Const LVCFMT_LEFT As Integer = &H0 Const LVCFMT_RIGHT As Integer = &H1 Const LVCFMT_CENTER As Integer = &H2 ' Sortierung Const HDF_SORTUP As Integer = &H400 Const HDF_SORTDOWN As Integer = &H200 ' http://msdn.microsoft.com/en-us/library/windows/desktop/bb774743%28v=vs.85%29.aspx <StructLayout(LayoutKind.Sequential, Charset:=CharSet.Auto)> Private Structure LVCOLUMN Public mask As UInteger Public fmt As Integer Public cx As Integer Public pszText As IntPtr Public cchTextMax As Integer Public iSubItem As Integer Public iImage As Integer Public iOrder As Integer End Structure <DllImport("User32.dll", CharSet:=CharSet.Auto)> Private Function SendMessage(ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As IntPtr End Function <DllImport("User32", CharSet:=CharSet.Auto)> Private Function SendMessage(hWnd As IntPtr, msg As Integer, wParam As Integer, ByRef lParam As LVCOLUMN) As IntPtr End Function End Module
SetColumnHeaderArrow setzt dabei den Pfeil und verwendet das eingestellte Alignment weiter.
GetColumnHeaderArrow liefert die eingestellte Sortierung, der jeweiligen Spalte.
Beide erwarten den ColumnHeader - was die Zahl der Parameter reduziert und es auch einfacher nutzbar macht.
Als Test via ColumnClick Ereignis:
Private PreviousColumn As Integer = -1 Private Sub ListView1_ColumnClick(ByVal sender As Object, ByVal e As System.Windows.Forms.ColumnClickEventArgs) _ Handles ListView1.ColumnClick Dim lvw = DirectCast(sender, ListView) If PreviousColumn <> e.Column Then If PreviousColumn >= 0 Then ' Löscht Sortierung der vorherigen Spalte ListViewNativeMethods.SetColumnHeaderArrow(lvw.Columns(PreviousColumn), ColumnHeaderArrow.None) End If End If PreviousColumn = e.Column Dim columnArrow = GetColumnHeaderArrow(lvw.Columns(PreviousColumn)) If columnArrow = ColumnHeaderArrow.None Then columnArrow = ColumnHeaderArrow.Down ElseIf columnArrow = ColumnHeaderArrow.Down Then columnArrow = ColumnHeaderArrow.Up Else columnArrow = ColumnHeaderArrow.None End If ListViewNativeMethods.SetColumnHeaderArrow(lvw.Columns(PreviousColumn), columnArrow) System.Diagnostics.Debug.WriteLine("ColumnClick {0} / {1}", e.Column, columnArrow) End Sub
Etwas vorläufig ist das immer Löschen der Sortierung für die vorherige Spalte.
Wobei denkbar wäre, die ColumnHeader Klasse zu erweitern, um das permanent zur Verfügung zu haben, braucht aber wiederum einen Designer etc. - bin ich jetzt aber erst einmal nicht angegangen.
Gruß Elmar
- Als Antwort markiert Migration Sucks Montag, 18. November 2013 15:48
Alle Antworten
-
Hallo,
übergebe ein 0 für die Pfeilrichtung (siehe das Enum weiter unten):SetColumnHeaderImage(ListView1, 0, HorizontalImageAlignment.Left, -1, Nothing, WindowsArrow.NOTHING)
Ich habe bei dem Aufruf UseWinArrows weg gelassen, da der Parameter bei deinem (verkürzten) Code unnötig ist.
Hier mein erweitertes Enum:
Public Enum WindowsArrow WIN_ARROW_UP = 1024 WIN_ARROW_DOWN = 512
Da die 0 oftmals der Standard ist habe ich das getestet und es funktionierte. (Unter Windows 8.1 x64 getestet)
NOTHING = 0'Neu hinzugefügt End Enum
Nun noch für alle Anderen, der fehlende Code stammt von hier:
http://social.msdn.microsoft.com/Forums/vstudio/en-US/60200f5a-5612-4322-934a-8016ee99d2b1/how-to-add-remove-listview-columnheader-sort-indicator-win-vista-vb-2008?forum=vbgeneralich%20f%C3%A4nde%20es%20aber%20schade,%20wenKoopakiller [kuːpakɪllɐ] (Tom Lambert)
Webseite |
Code Beispiele |
Facebook |
Twitter |
Snippets
C# ↔ VB.NET Konverter
Markiert bitte beantwortende Posts als Antwort und bewertet Beiträge. Danke.- Als Antwort markiert Migration Sucks Montag, 18. November 2013 15:48
-
Hallo Thomas,
ich habe da etwas aufgeräumt und ergänzt. Vorläufig ist dabei herausgekommen - weitere Tests Deinerseits sind empfehlenswert:
''' <summary>Anzeige der Sortierung im ListView ColumnHeader</summary> Public Enum ColumnHeaderArrow ''' <summary>kein Pfeil.</summary> None = 0 ''' <summary>Pfeil nach oben.</summary> Up = 1 ''' <summary>Pfeil nach unten.</summary> Down = 2 End Enum Public Module ListViewNativeMethods ''' <summary> ''' Setzt oder löscht die Anzeige eines Pfeiles in einer ListView Überschrift ''' </summary> ''' <param name="header">Die Spalte.</param> ''' <param name="order">Die Sortierung.</param> Public Sub SetColumnHeaderArrow(header As ColumnHeader, order As ColumnHeaderArrow) Dim lvw = header.ListView If lvw.IsHandleCreated Then 'Dim hwnd As IntPtr = SendMessage(lvw.Handle, LVM_GETHEADER, 0, 0) Dim column As LVCOLUMN column.mask = LVCF_FMT 'Or LVCF_IMAGE Select Case header.TextAlign Case HorizontalAlignment.Right column.fmt = LVCFMT_RIGHT Case HorizontalAlignment.Center column.fmt = LVCFMT_CENTER Case Else column.fmt = LVCFMT_LEFT End Select If order = ColumnHeaderArrow.Up Then column.fmt = column.fmt Or HDF_SORTUP ElseIf order = ColumnHeaderArrow.Down Then column.fmt = column.fmt Or HDF_SORTDOWN End If column.iImage = 0 SendMessage(lvw.Handle, LVM_SETCOLUMN, header.Index, column) End If End Sub ''' <summary> ''' Liefert die Anzeige eines Pfeiles in einer ListView Überschrift ''' </summary> ''' <param name="header">Die Spalte.</param> ''' <returns>Die Sortierung.</returns> Public Function GetColumnHeaderArrow(header As ColumnHeader) As ColumnHeaderArrow Dim lvw = header.ListView If lvw.IsHandleCreated Then 'Dim hwnd As IntPtr = SendMessage(lvw.Handle, LVM_GETHEADER, 0, 0) Dim column As LVCOLUMN column.mask = LVCF_FMT If SendMessage(lvw.Handle, LVM_GETCOLUMN, header.Index, column) <> IntPtr.Zero Then If (column.fmt And HDF_SORTDOWN) = HDF_SORTDOWN Then Return ColumnHeaderArrow.Down ElseIf (column.fmt And HDF_SORTUP) = HDF_SORTUP Then Return ColumnHeaderArrow.Up End If End If End If Return ColumnHeaderArrow.None End Function Const LVM_GETCOLUMN = 4121 Const LVM_SETCOLUMN = 4122 Const LVM_GETHEADER = 4127 Const LVCF_FMT = 1 Const LVCF_IMAGE = 16 Const LVCFMT_IMAGE = 2048 ' Ausrichtung Const LVCFMT_LEFT As Integer = &H0 Const LVCFMT_RIGHT As Integer = &H1 Const LVCFMT_CENTER As Integer = &H2 ' Sortierung Const HDF_SORTUP As Integer = &H400 Const HDF_SORTDOWN As Integer = &H200 ' http://msdn.microsoft.com/en-us/library/windows/desktop/bb774743%28v=vs.85%29.aspx <StructLayout(LayoutKind.Sequential, Charset:=CharSet.Auto)> Private Structure LVCOLUMN Public mask As UInteger Public fmt As Integer Public cx As Integer Public pszText As IntPtr Public cchTextMax As Integer Public iSubItem As Integer Public iImage As Integer Public iOrder As Integer End Structure <DllImport("User32.dll", CharSet:=CharSet.Auto)> Private Function SendMessage(ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As IntPtr End Function <DllImport("User32", CharSet:=CharSet.Auto)> Private Function SendMessage(hWnd As IntPtr, msg As Integer, wParam As Integer, ByRef lParam As LVCOLUMN) As IntPtr End Function End Module
SetColumnHeaderArrow setzt dabei den Pfeil und verwendet das eingestellte Alignment weiter.
GetColumnHeaderArrow liefert die eingestellte Sortierung, der jeweiligen Spalte.
Beide erwarten den ColumnHeader - was die Zahl der Parameter reduziert und es auch einfacher nutzbar macht.
Als Test via ColumnClick Ereignis:
Private PreviousColumn As Integer = -1 Private Sub ListView1_ColumnClick(ByVal sender As Object, ByVal e As System.Windows.Forms.ColumnClickEventArgs) _ Handles ListView1.ColumnClick Dim lvw = DirectCast(sender, ListView) If PreviousColumn <> e.Column Then If PreviousColumn >= 0 Then ' Löscht Sortierung der vorherigen Spalte ListViewNativeMethods.SetColumnHeaderArrow(lvw.Columns(PreviousColumn), ColumnHeaderArrow.None) End If End If PreviousColumn = e.Column Dim columnArrow = GetColumnHeaderArrow(lvw.Columns(PreviousColumn)) If columnArrow = ColumnHeaderArrow.None Then columnArrow = ColumnHeaderArrow.Down ElseIf columnArrow = ColumnHeaderArrow.Down Then columnArrow = ColumnHeaderArrow.Up Else columnArrow = ColumnHeaderArrow.None End If ListViewNativeMethods.SetColumnHeaderArrow(lvw.Columns(PreviousColumn), columnArrow) System.Diagnostics.Debug.WriteLine("ColumnClick {0} / {1}", e.Column, columnArrow) End Sub
Etwas vorläufig ist das immer Löschen der Sortierung für die vorherige Spalte.
Wobei denkbar wäre, die ColumnHeader Klasse zu erweitern, um das permanent zur Verfügung zu haben, braucht aber wiederum einen Designer etc. - bin ich jetzt aber erst einmal nicht angegangen.
Gruß Elmar
- Als Antwort markiert Migration Sucks Montag, 18. November 2013 15:48
-