[R] Tri ListView _GUICtrlListView_SortItems et custom Sort

Aide sur les Interfaces Graphique Utilisateurs (GUI).
Règles du forum
.
Répondre
keltharak
Niveau 3
Niveau 3
Messages : 40
Enregistré le : lun. 12 janv. 2009 16:35
Status : Hors ligne

[R] Tri ListView _GUICtrlListView_SortItems et custom Sort

#1

Message par keltharak »

Bonjour,

J'ai un script qui crée une listview à partir d'une base de donné mais je veux réorganiser ma listview selon ma propre méthode de tri. J'utilise la fonction

Code : Tout sélectionner

GUICtrlRegisterListViewSort($listview, "LVSort")
pour associer ma fonction de tri à ma listview. Jusque là tout fonctionne, mais maintenant je voudrais lancer ce tri depuis mon script juste après la génération de la listview, et sans intervention de l'utilisateur.
Comment puis-je faire pour simuler un click sur la colonne que je veux trier ou-bien directement déclencher le tri de la listview mais en utilisant ma fonction de tri ?

Merci d'avance,

EDIT : J'ai modifier le titre du topic pour qu'il corresponde plus à la solution présenté sur le message 7.
Modifié en dernier par keltharak le ven. 31 mai 2013 09:33, modifié 2 fois.
Avatar du membre
mikell
Spammer !
Spammer !
Messages : 6292
Enregistré le : dim. 29 mai 2011 17:32
Localisation : Deep Cévennes
Status : Hors ligne

Re: [..] Tri de ListView sans evenement

#2

Message par mikell »

_GUICtrlListView_SimpleSort() ne marche pas ?
" L'échec est le fondement de la réussite. " (Lao-Tseu )
" Plus ça rate, plus on a de chances que ça marche " (les Shadoks )
keltharak
Niveau 3
Niveau 3
Messages : 40
Enregistré le : lun. 12 janv. 2009 16:35
Status : Hors ligne

Re: [..] Tri de ListView sans evenement

#3

Message par keltharak »

Bonjour,

Si, la commande en elle-même fonctionne mais elle ne correspond pas a ce que je recherche. Le tri avec le SimpleSort se fait en fonction du code ascii de la chaine de caractère contenu dans l'item, ma fonction de tri n'est pas utilisée.
Je voudrais pouvoir lancer un tri qui utilise cette fonction justement, comme lorsque je clique sur l’entête de ma colonne.
GaRydelaMer
Niveau 7
Niveau 7
Messages : 450
Enregistré le : mer. 18 mars 2009 22:12
Localisation : Montpellier
Status : Hors ligne

Re: [..] Tri de ListView sans evenement

#4

Message par GaRydelaMer »

Bonjour

puisque tu créer ta liste à partir de ta base de données, utilise le SQL pour renvoyer les données trier de la base.
keltharak
Niveau 3
Niveau 3
Messages : 40
Enregistré le : lun. 12 janv. 2009 16:35
Status : Hors ligne

Re: [..] Tri de ListView sans evenement

#5

Message par keltharak »

La fonction de tri que j'utilise n'a rien de commun et un simple order by ne fonctionne pas et la base de donné est embarqué avec mon script en SQLite, donc impossible, à ma connaissance, d'utiliser une procédure SQL pour faire ce tri.

De plus, maintenant que tout fonctionne en autoit je n'ai pas vraiment envie de tout refaire ! Il doit bien exister un moyen de lancer le tri d'une listview sans devoir cliquer sur l’entête de la colonne non ?
Avatar du membre
GhostLine
Niveau 7
Niveau 7
Messages : 342
Enregistré le : jeu. 12 mars 2009 15:28
Localisation : Paris
Status : Hors ligne

Re: [..] Tri de ListView sans evenement

#6

Message par GhostLine »

Tu ne peux pas utiliser un siouxage du genre :


[déclarations]
...
$switch = 0
...

Case $switch = 0
[génération de la listview]
...
$switch = 1

Case $switch = 1
[rafraichissement de la listview]
...
$switch = 2

Par exemple ?
keltharak
Niveau 3
Niveau 3
Messages : 40
Enregistré le : lun. 12 janv. 2009 16:35
Status : Hors ligne

Re: [..] Tri de ListView sans evenement

#7

Message par keltharak »

Le problème n'est pas vraiment de savoir à quel moment je doit faire mon tri mais plutôt par quelle commande je dois remplacer [rafraichissement de la listview] ...

Enfin merci a tous d'avoir réfléchi à mon problème mais j'ai finalement trouvé une solution hier. J'ai modifié l'UDF GUIListView et la fonction _GUICtrlListView_RegisterSortCallBack() pour qu'elle accepte en paramètre une fonction de tri custom.

Code : Tout sélectionner

Func _GUICtrlListView_RegisterSortCallBack2($hWnd, $sFuncSortCallBck, $fNumbers = True, $fArrows = True)
    If $Debug_LV Then __UDF_ValidateClassName($hWnd, $__LISTVIEWCONSTANT_ClassName)
    If Not IsHWnd($hWnd) Then $hWnd = GUICtrlGetHandle($hWnd)

    Local $hHeader = _GUICtrlListView_GetHeader($hWnd)

    ReDim $aListViewSortInfo[UBound($aListViewSortInfo) + 1][$iLListViewSortInfoSize]

    $aListViewSortInfo[0][0] = UBound($aListViewSortInfo) - 1
    Local $iIndex = $aListViewSortInfo[0][0]

    $aListViewSortInfo[$iIndex][1] = $hWnd ; Handle/ID of listview

    $aListViewSortInfo[$iIndex][2] = _
            DllCallbackRegister($sFuncSortCallBck, "int", "int;int;hwnd") ; Handle of callback
    $aListViewSortInfo[$iIndex][3] = -1 ; $nColumn
    $aListViewSortInfo[$iIndex][4] = -1 ; nCurCol
    $aListViewSortInfo[$iIndex][5] = 1 ; $nSortDir
    $aListViewSortInfo[$iIndex][6] = -1 ; $nCol
    $aListViewSortInfo[$iIndex][7] = 0 ; $bSet
    $aListViewSortInfo[$iIndex][8] = $fNumbers ; Treat as numbers?
    $aListViewSortInfo[$iIndex][9] = $fArrows ; Use arrows in the header of the columns?
    $aListViewSortInfo[$iIndex][10] = $hHeader ; Handle to the Header

    Return $aListViewSortInfo[$iIndex][2] <> 0
EndFunc   ;==>_GUICtrlListView_RegisterSortCallBack2
Ensuite j'ai modifier la fonction de tri que j'utilisais avec GUICtrlRegisterListViewSort() pour quelle soit appeler comme la fonction __GUICtrlListView_Sort($nItem1, $nItem2, $hWnd) de l'UDF ( à savoir 2 entier correspondant au index des item a comparer et le handle de la listview à trier). De cette manière a la création de mes listview je leur associe ma fonction de tri :

Code : Tout sélectionner

$listview = GUICtrlCreateListView("Col1|Col2|Col3", 0, 20, 698, 760)
_GUICtrlListView_RegisterSortCallBack2($listview, "__LVSort", True, False)
et on lance le tri comme ça :

Code : Tout sélectionner

_GUICtrlListView_SortItems(GUICtrlGetHandle($listview), 0)
Pour la fonction __LVSort de tri, il suffit de s'inspirer de l'exemple de l'aide donné pour la fonction GuiCtrlRegisterListviewSort et retrouver les numéros de dans la fonction :

Code : Tout sélectionner

Func __LVSort($nItem1, $nItem2, $hWnd)
    Local $iIndex, $tInfo, $val1, $val2, $nResult
    $tInfo = DllStructCreate($tagLVFINDINFO)
    DllStructSetData($tInfo, "Flags", $LVFI_PARAM)

    For $x = 1 To $aListViewSortInfo[0][0]
        If $hWnd = $aListViewSortInfo[$x][1] Then
            $iIndex = $x
            ExitLoop
        EndIf
    Next

    $aListViewSortInfo[$iIndex][6] = $aListViewSortInfo[$iIndex][3] ; $nCol = $nColumn
    $nColumn = $aListViewSortInfo[$iIndex][3]

        ; on récupère les valeurs à comparer 
    DllStructSetData($tInfo, "Param", $nItem1)
    $valItem1 = _GUICtrlListView_FindItem($hWnd, -1, $tInfo)
    DllStructSetData($tInfo, "Param", $nItem2)
    $valItem2 = _GUICtrlListView_FindItem($hWnd, -1, $tInfo)
    $val1 = _GUICtrlListView_GetItemText($hWnd, $valItem1, $aListViewSortInfo[$iIndex][3])
    $val2 = _GUICtrlListView_GetItemText($hWnd, $valItem2, $aListViewSortInfo[$iIndex][3])

        ; on met en forme ces valeurs (ici comparaison d'interface d'équipements réseaux)
    If $nColumn = 0 Then
        If $val1 = $val2 Then
            $val1 = _GUICtrlListView_GetItemText($hWnd, $valItem1, 1)
            $val2 = _GUICtrlListView_GetItemText($hWnd, $valItem2, 1)
            $offset1 = 0
            $offset2 = 0
            If StringLeft($val1, 2) = "RE" Then $offset1 = -10
            If StringLeft($val2, 2) = "RE" Then $offset2 = -10
            If StringRegExp($val1, "g\d+", 0) Then $offset1 = 100
            If StringRegExp($val2, "g\d+", 0) Then $offset2 = 100
            $val1 = Int(StringRegExpReplace($val1, "[^\d]", "")) + $offset1
            $val2 = Int(StringRegExpReplace($val2, "[^\d]", "")) + $offset2
        Else
            If StringRegExp($val1, "H\d+", 0) And StringRegExp($val2, "H\d+", 0) Then
                $val1 = Int(StringTrimLeft($val1, 1))
                $val2 = Int(StringTrimLeft($val2, 1))
            EndIf
        EndIf
    EndIf
         
         ; on compare les valeurs pour retourner -1 1 ou 0
    $nResult = 0 ; No change of item1 and item2 positions

    If $val1 < $val2 Then
        $nResult = -1 ; Put item2 before item1
    ElseIf $val1 > $val2 Then
        $nResult = 1 ; Put item2 behind item1
    EndIf

    $nResult = $nResult * $aListViewSortInfo[$iIndex][5] ; $nSortDir

    Return $nResult
EndFunc   ;==>__GUICtrlListView_Sort
C'est pas simple mais ça fonctionne bien. Je suis tout de même très étonné qu'il n'existe pas un moyen de faire la même chose en partant de la fonction GuiCtrlRegisterListviewSort.

Merci encore pour votre aide.
Répondre