Page 1 of 1

Sort a ListViewGadget -- How to?

Posted: Wed Nov 05, 2025 1:53 am
by Randy Walker
I was hoping for maybe a one step API to sort my listViewGadget but cannot find if it exists. Any simple way to sort a populated listViewGadget?

Re: Sort a ListViewGadget -- How to?

Posted: Wed Nov 05, 2025 4:27 am
by idle
no there's no autosorting on a listview that I'm aware of
the simple way is to fill the listview with n items from an array of values then sort the array and swap the positions in the listview as such. If you use numbers in the string then you should set them with Rset so you can sort it numerically

Code: Select all

Global Dim Lvitems.s(20) 
For a = 0 To 19 
  lvitems.s(a) = "item:" + RSet(Str(19-a),3,"0") 
Next 

Procedure sortlisview(gadget) 
  
  SortArray(lvitems(),#PB_Sort_Ascending | #PB_Sort_NoCase)  
  For a = 0 To ArraySize(lvitems()) 
    SetGadgetItemText(gadget,a-1,Lvitems(a)) 
  Next  
  
EndProcedure   

If OpenWindow(0, 0, 0, 270, 140, "ListViewGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    ListViewGadget(0, 10, 10, 250, 120)
    For a = 0 To ArraySize(lvitems())
      AddGadgetItem (0, -1, lvitems(a)) ; define listview content
    Next
    sortlisview(0) 
    SetGadgetState(0, 9) ; set (beginning with 0) the tenth item as the active one
    Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf

Re: Sort a ListViewGadget -- How to?

Posted: Wed Nov 05, 2025 4:43 am
by Randy Walker
Thanks for the effort there idle. No Simple way is what I thought. Was looking for a way to sort a pre-populated listViewGadget. What I ended up doing is copy the items into list, sort the list, clear the listbox and repopulate from the sorted list. Could do with an array. I just thought the list would be simpler since the number of items in the listbox are subject to frequent unpredictable change.

Re: Sort a ListViewGadget -- How to?

Posted: Wed Nov 05, 2025 5:32 am
by RASHAD
Hi
Quick hack not tested :D

Code: Select all

OpenWindow(0, 0, 0, 800,600, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ListViewGadget(0, 10, 10, 780, 500, #LBS_SORT | #LBS_NOINTEGRALHEIGHT | #LBS_HASSTRINGS)
StringGadget(1, 10, 515, 400, 24, "")
ButtonGadget(2, 10, 542, 160, 24, "Add Item")
ButtonGadget(3, 10, 570, 160, 24, "Sort Items")

AddGadgetItem(0,-1,"My new item")
AddGadgetItem(0,-1,"Any new item")
AddGadgetItem(0,-1,"For test")

SetActiveGadget(0)
 Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Quit = 1
      
    Case #PB_Event_Gadget
        Select EventGadget()
          Case 2
            String$ = GetGadgetText(1)
            SendMessage_(GadgetID(0), #LB_ADDSTRING, 0, string$)
            SetGadgetText(1, "")
            SetActiveGadget(0)
            
          Case 3
            For item = 0 To CountGadgetItems(0)
              SendMessage_(GadgetID(0), #LB_ADDSTRING, 0, GetGadgetItemText(0,0))
              RemoveGadgetItem(0,0)
            Next
        EndSelect
     EndSelect
Until Quit = 1
End
This one is tested :mrgreen:

Code: Select all

OpenWindow(0, 0, 0, 800,600, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ListViewGadget(0, 10, 10, 780, 500, #LBS_SORT | #LBS_NOINTEGRALHEIGHT | #LBS_HASSTRINGS)
ListViewGadget(1, -800, 10, 385, 500, #LBS_SORT | #LBS_NOINTEGRALHEIGHT | #LBS_HASSTRINGS)  ;dummy ListView
StringGadget(2, 10, 515, 400, 24, "")
ButtonGadget(3, 10, 542, 160, 24, "Add Item")
ButtonGadget(4, 10, 570, 160, 24, "Sort Items")

AddGadgetItem(0,-1,"My new item")
AddGadgetItem(0,-1,"Any new item")
AddGadgetItem(0,-1,"X For test")
AddGadgetItem(0,-1,"Q For test")
AddGadgetItem(0,-1,"9 For test")
AddGadgetItem(0,-1,"1 For test")

SetActiveGadget(0)
Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Quit = 1
      
    Case #PB_Event_Gadget
      Select EventGadget()
        Case 3
          String$ = GetGadgetText(2)
          SendMessage_(GadgetID(0), #LB_ADDSTRING, 0, string$)
          SetGadgetText(2, "")
          SetActiveGadget(0)
          
        Case 4
          For item = 0 To CountGadgetItems(0)-1
            SendMessage_(GadgetID(1), #LB_ADDSTRING, item , GetGadgetItemText(0,item))
          Next
          ClearGadgetItems(0)
          For item = 0 To CountGadgetItems(1)-1
            SendMessage_(GadgetID(0), #LB_ADDSTRING, 0 , GetGadgetItemText(1,item))
          Next
          FreeGadget(1)
      EndSelect
  EndSelect
Until Quit = 1
End


Re: Sort a ListViewGadget -- How to?

Posted: Wed Nov 05, 2025 6:05 am
by Randy Walker
RASHAD wrote: Wed Nov 05, 2025 5:32 am Hi
Quick hack not tested :D
I don't understand how it works, but it does perfectly.
Thanks RASHAD!!!!

Re: Sort a ListViewGadget -- How to?

Posted: Wed Nov 05, 2025 9:35 am
by Rinzwind
"LB_ADDSTRING message
Adds a string to a list box. If the list box does not have the LBS_SORT style, the string is added to the end of the list. Otherwise, the string is inserted into the list and the list is sorted."

ps Not the most elegant way to continually sort it every time an item is added (readded).

But yeah, should come as out-of-the-box functionality in PB. The controls are severely bare bones one on one mappings with decades old OS controls.

Re: Sort a ListViewGadget -- How to?

Posted: Wed Nov 05, 2025 11:48 am
by Mesa
With big datas, you can use sqlite:

Code: Select all

Enumeration
  #MainForm
  #MainList
  #Filters
  #Tri
EndEnumeration

UseSQLiteDatabase()
Global DB = OpenDatabase(#PB_Any, ":memory:", "", "", #PB_Database_SQLite)

Procedure CreateTable()
  Protected query.s
  query = "CREATE TABLE client ("
  query + "name TEXT)"
  If DatabaseUpdate(DB, query) = 0
    MessageRequester("Database Error", "Can not create table")
    ProcedureReturn #False
  EndIf
  ProcedureReturn #True
EndProcedure

Procedure FillTable(name.s)
  Protected query.s
  query = "INSERT INTO client ("
  query + "name) VALUES (" + Chr(34) + name + Chr(34) + ")"
  If DatabaseUpdate(DB, query) = 0
    MessageRequester("Database Error", DatabaseError())
    ProcedureReturn #False
  EndIf
  ProcedureReturn #True
EndProcedure

Procedure MakeClient()
  FillTable("Grumeaux")
  FillTable("Maurico")
  FillTable("Grosard")
  FillTable("Foulard")
  FillTable("Faulard")
  FillTable("Faumard")
EndProcedure

Procedure FillList()
  Protected Filters.s = GetGadgetText(#Filters)
  Protected query.s
  query = "SELECT name FROM client"
  ; Si il y à un filtre je l'ajoute
  If Filters <> ""
    query + " WHERE name LIKE '" + Filters + "%'"
  EndIf
  If DatabaseQuery(DB, query) = 0
    MessageRequester("Database Error", DatabaseError())
    ProcedureReturn #False
  EndIf
  ClearGadgetItems(#MainList)
  While NextDatabaseRow(DB)
    AddGadgetItem(#MainList,  - 1, GetDatabaseString(DB, 0))
  Wend
EndProcedure

Procedure SortMe()
  ; 	  DatabaseQuery(DB, "Select * From client Order By Substr(name, 1, 1), Cast(Substr(name, 2, 10) As Int)"); ex; A1 A2 A10
  DatabaseQuery(DB, "Select * From client Order By name ASC"); ex; A1 A10 A2
  ClearGadgetItems(#MainList)
  While NextDatabaseRow(DB)
    AddGadgetItem(#MainList,  - 1, GetDatabaseString(DB, 0))
  Wend
EndProcedure

Procedure Exit()
  End
EndProcedure


CreateTable()

MakeClient()


Define flag = #PB_Window_SystemMenu | #PB_Window_ScreenCentered
Define X    = 10, Y = 10, WF = 800, HF = 600
OpenWindow(#MainForm, 0, 0, WF, HF, "Test filtre", flag)
TextGadget(#PB_Any, X, Y, 100, 30, "Filtre:")
Y + 20
StringGadget(#Filters, X, Y, 100, 30, "")
ButtonGadget(#Tri, 150, Y, 60, 30, "Sort")
Y + 40
ListViewGadget(#MainList, X, Y, WF - 20, HF - (Y + 10))
BindEvent(#PB_Event_CloseWindow, @Exit(), #MainForm)
BindGadgetEvent(#Filters, @FillList())
BindGadgetEvent(#Tri, @SortMe())
FillList()

; MainLoop
Repeat:WaitWindowEvent():ForEver

M.

Re: Sort a ListViewGadget -- How to?

Posted: Wed Nov 05, 2025 9:24 pm
by Randy Walker
Mesa wrote: Wed Nov 05, 2025 11:48 am With big datas, you can use sqlite:

M.
Hey that's pretty good. A little overkill maybe.
Now I'd like to see you do the traditional "Hello World" with SQL. :mrgreen:

Some people think the solution to everything is put it into SQL. :headbang:

BTW... Why is there no :headbang: in here?