Newsgroup: it.comp.lang.visual-basic
Titolo: [!] Interessante sub x ListBox

Questa mia sub sposta di una posizione in alto o in basso l'elemento
selezionato in una ListBox. Ve la posto così potete commentarla e
MIGLIORARLA! Ok?
Eccola qua!
In una form mettete una ListBox (List1) e due CommandButton (cmdUp e
cmdDown). Quindi fate un copia e incolla di questo codice:
'---BEGIN
Option Explicit
' Enum utilizzata da ListBoxUpDown
Public Enum ListBoxUpDownAction
    Up = 0
    Down = 1
End Enum
Public Sub ListBoxUpDown(myListBox As ListBox, Action As
ListBoxUpDownAction)
    Dim Selected As String
    Dim NewSelected As String
    Dim Index As Integer
    Dim Items() As String
    Dim i As Long
    Dim j As Long
    ' Memorizzo l'index dell'elemento selezionato
    Index = myListBox.ListIndex
    ' Se index=-1 non è selezionato nulla! Esco!
    If Index = -1 Then Exit Sub
    ' Cosa devo fare?
    Select Case Action
        Case Up ' Andare in sù
            If Index = 0 Then Exit Sub
        Case Down ' Andare in giù
            If Index = myListBox.ListCount - 1 Then Exit Sub
    End Select
    ' Memorizzo quello che c'è scritto.
    Selected = myListBox.List((myListBox.ListIndex))
    ' Memorizzo la ListBox in un mio vettore.
    For i = 0 To myListBox.ListCount - 1
        ReDim Preserve Items(i)
        Items(i) = myListBox.List(i)
    Next i
    myListBox.Visible = False
    ' Cosa devo fare?
    Select Case Action
        Case Up ' Spostare in sù.
            Items(Index) = Items(Index - 1)
            Items(Index - 1) = Selected
            Index = Index - 1
        Case Down ' Spostare in giù.
            Items(Index) = Items(Index + 1)
            Items(Index + 1) = Selected
            Index = Index + 1
    End Select
    ' Pulisco la listbox
    myListBox.Clear
    ' E la ripopolo con il vettore.
    For j = 0 To i - 1
        myListBox.AddItem Items(j)
    Next j
    myListBox.Visible = True
    ' Seleziono l'item già selezionato prima.
    myListBox.Selected(Index) = True
End Sub
Private Sub cmdDown_Click()
    ListBoxUpDown List1, Down
End Sub
Private Sub cmdUp_Click()
    ListBoxUpDown List1, Up
End Sub
Private Sub Form_Load()
    List1.AddItem "Item 1"
    List1.AddItem "Item 2"
    List1.AddItem "Item 3"
    List1.AddItem "Item 4"
    List1.AddItem "Item 5"
    List1.AddItem "Item 6"
    List1.AddItem "Item 7"
    List1.AddItem "Item 8"
    List1.AddItem "Item 9"
    List1.AddItem "Item 10"
    List1.AddItem "Item 11"
    List1.AddItem "Item 12"
    List1.AddItem "Item 13"
    List1.AddItem "Item 14"
    List1.AddItem "Item 15"
    List1.AddItem "Item 16"
    List1.AddItem "Item 17"
    List1.AddItem "Item 18"
End Sub
'---END
Hope This Help!
ByeZ
ByeZ
SebaMix

 Hope This Help!
Anca mi.
--
Ciao.
Maurizio
--------
?SPQR(C)
 X
--------

 Considera il codice seguente e prova a completarlo perche' esegua la
stessa cosa del tuo, poi facci sapere. Magari fatti aiutare da Cesare Rizzi.
Dalla sua "Raccolta", intendo...
[...]
Scusami. Riguardando il tuo post mi sono accorto che avevi bisogno di un
altro tipo di "stimolo".
Esplicito per non essere frainteso: col mio precedente post intendevo
invitarti a prendere in considerazione l'uso di alcuni semplici messaggi
dell'API che nel caso delle listbox possono essere veramente vantaggiosi ed
"economici", intendendo con questo il rapporto (impegno di
studio)/risultato.
Pero` l'esempio da me proposto non era particolarmente significativo,
ripensandoci direi fosse proprio un esempio che contraddiceva quello che
intendevo dire ma, come si dice... e` il pensiero che conta, no?... :-( :-)
Ed ora ti sottopongo il codice seguente, forse imperfetto ma, spero,
stimolante, utile. Piu` del mio precedente, almeno.
Option Explicit
Private Function UpDown( _
  ByRef ListBox As VB.ListBox _
, ByVal Up As Boolean _
) As Long
  Dim strItem   As String
  Dim lngCount  As Long
  With ListBox
    UpDown = .ListIndex
    lngCount = .ListCount - 1
    If (Up And (0 < UpDown And UpDown <= lngCount)) _
    Or (Not Up And (0 <= UpDown And UpDown < lngCount)) _
    Then
      strItem = .List(UpDown)
      .RemoveItem UpDown
      UpDown = UpDown + 1 * (Up = True) - 1 * (Up = False)
      .AddItem strItem, UpDown
    Else
      Beep
    End If
  End With
End Function
Private Sub Command1_Click( _
)
  List1.SetFocus
  List1.ListIndex = UpDown(ListBox:=List1, Up:=True)
End Sub
Private Sub Command2_Click( _
)
  List1.SetFocus
  List1.ListIndex = UpDown(ListBox:=List1, Up:=False)
End Sub
Private Sub Form_Load( _
)
  With List1
    .AddItem "Pippo"
    .AddItem "Pluto"
    .AddItem "Paperino"
  End With
  Command1.Caption = "Sposta su"
  Command2.Caption = "Sposta giů"
End Sub


    For i = 0 To myListBox.ListCount - 1
 >       ReDim Preserve Items(i)
 >      Items(i) = myListBox.List(i)
 >  Next i
non era meglio fare redim items(mylistbox.count-1) fuori dal ciclo?
Per il resto sono d'accordo con quanto ha scritto Maurizio: il problema č
semplice: che bisogno c'č di copiarsi tutta la lista e poi riempirla daccapo
quando basta rimuovere l'elemento selezionato e reinserirlo al posto giusto?

 quando basta rimuovere l'elemento selezionato e reinserirlo al posto
giusto?
In effetti. Ma l'avevo fatto senza avere MAI visto una ListBox in vita mia
(o quasi)... :)
Ho provato a guardare MSDN ma mi è venuto mal di testa dopo 15 min...
:::::::)))))))))
Grazie per le critiche costruttive! La sistemo e poi ve la rimando (forse
dopo la pausa pranzo!) ;)
CiaoZ
SebaMix


Si, ma quello che volevo dire è che se ci sono 4 listbox, quando premo il
pulsante "up", per es., non posso eseguire incondizionatamente
listboxupdown(listboxes(3),up), perchè magari voglio aggiornare la prima
listbox: quindi bisognerebbe fare listboxupdown(listboxes(indice),up), dove
indice lo aggiorni man mano che l'utente fa clic sulle varie listbox

[...]
Option Explicit
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'' ListBoxUpDown                                                    ''
''                                                                  ''
'' Sub per la gestione dello spostamento di un elemento in una      ''
'' ListBox.                                                         ''
'' Programmato da Pallaro Sebastiano, Maurizio Borrelli, Giorgio1.  ''
'' Un ringraziamento a tutto il NewsGroup it.comp.lang.visual-basic.''
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Enum utilizzata da ListBoxUpDown
Public Enum ListBoxUpDownAction
    Up = 0
    down = 1
    toBegin = 2
    toEnd = 3
End Enum
Public Sub ListBoxUpDown(myListBox As ListBox, Action As
ListBoxUpDownAction)
    Dim strSelected As String
    Dim Index As Integer
    Dim NewIndex As Integer
    ' Memorizzo l'index dell'elemento selezionato
    Index = myListBox.ListIndex
    ' Se index=-1 non è selezionato nulla! Esco!
    If Index = -1 Then Exit Sub
    ' Cosa devo fare?
    Select Case Action
        Case Up ' Andare in sù
            If Index = 0 Then Exit Sub
            NewIndex = Index - 1
        Case down ' Andare in giù
            If Index = myListBox.ListCount - 1 Then Exit Sub
            NewIndex = Index + 1
        Case toBegin ' Andare all'inizio della lista
            If Index = 0 Then Exit Sub
            NewIndex = 0
        Case toEnd ' Andare alla fine della lista
            If Index = myListBox.ListCount - 1 Then Exit Sub
            NewIndex = myListBox.ListCount - 1
    End Select
    ' Memorizzo quello che c'è scritto.
    strSelected = myListBox.List((myListBox.ListIndex))
    ' Sposto l'item selezionato nella posizione giusta.
    myListBox.RemoveItem Index
    myListBox.AddItem strSelected, NewIndex
    ' Seleziono l'item già selezionato prima.
    myListBox.Selected(NewIndex) = True
End Sub
Ecco una soluzione migliorata. Quella di Maurizio è troppo complicata da
capire (anche se è + veloce di questa). Che ne dite?
CiaoZ
e GRAZIE 1000!
SebaMix

 Per il resto sono d'accordo con quanto ha scritto Maurizio: il problema è
semplice: che bisogno c'è di copiarsi tutta la lista e poi riempirla daccapo
quando basta rimuovere l'elemento selezionato e reinserirlo al posto giusto?
Aspettiamo di vedere cosa ci dice Sebastiano. I casi sono due: o tu ed io
non abbiamo colto qualcosa che Sebastiano ci spieghera`, o lui e` troppo
sensibile e sta scrivendo e riscrivendo post di risposta tentando di venirne
fuori dignitosamente. Coraggio, bello! ;-) Guarda che siamo tutti dalla tua
parte, sai?


 parte, sai?
;)
La mia seconda soluzione č un'ibrido tra quella proposta da giorgio1,
Maurizio e la mia.
Ditemi cosa ne pensate! Poi magari la mando al SC!
;)
CiaoZ!
[...]

 (anche se è + veloce di questa). Che ne dite?
--


 ha scritto nel messaggio
news:94p65a$e2hpf$4...@ID-52090.news.dfncis.de...


 Ok. tolgo tutti i nomi (che non erano nomi ma ringraziamenti) e mi firmo
solo io?
Vai tranquillo come preferisci. Come vedi parlavo della "prossima" volta.
Perche' questa ormai e` andata. I post dei ng dopotutto non hanno una vita
cosi` effimera e quel che e` fatto e` fatto. Amen.


 cosi` effimera e quel che e` fatto e` fatto. Amen.
Ma guarda che se il tuo nome appare mica ti diffama o ti obbliga a comperare
un'enciclopedia ;;;))))
La prossima volta metto semplicemente un ringraziamento a tutto il
NewsGroup.
CiaoZ

> Sebastiano Pallaro:

Sebastia'!... Ma vuoi proprio costringermi a essere precisino asfittico?
Guarda che mi viene bene. ;-))
La *firma* e` una cosa, tutto il resto un'altra ancora. Hai torto, torto
marcio perche' NON si fa quello che hai fatto tu. Mi rendo conto che il caso
in questione e` poca cosa e puo` apparire ridicolo questo nostro durare
sull'argomento, ma io ci ho tenuto a fartelo notare non per problemi miei ma
per il solito proverbiale "tuo bene". Perche' se ti dovesse capitare con
qualcosa di appena un po' piu` importante di quello di cui stiamo parlando
potresti avere delle seccature. Non prenderla cosi` alla leggera. Ringrazia
chi vuoi, me, Pippo, Pluto o Paperino, tutto il ng o solo meta`, me non
mettere MAI la firma di qualcun altro in nessun posto senza averne prima
avuto l'autorizzazione. Scritta.
--
Ciao:-))


 posizione successivamente selezionata", non trovi?
Sě, certo, dipende un po' dai gusti: a questo punto forse varrebbe la pena
di implementare il drag/drop

 capire (anche se č + veloce di questa). Che ne dite?
troppo complicata da leggere, senz'altro: perň ha un suo fascino. Avrei solo
un paio di osservazioni: io toglierei l'"else beep" che mi pare un po'
fastidioso, e metterei come tipo restituito dalla funzione Integer anzichč
Long: se non sbaglio una listbox non puň contenere piů di 32767 elementi. O
no?

 e metterei come tipo restituito dalla funzione Integer anzichč Long: se
non sbaglio una listbox non puň contenere piů di 32767 elementi. O no?
A parte il fatto che una variabile piu` abbondante metterebbe al sicuro
riguardo ad una eventuale nuova versione del linguaggio in modo che non
dovresti toccare il codice nel caso le future implementazioni dovessero
permettere una gestione di piu` di 32.767 elementi, mi pare che tale limite
esista per Win9x ma non per WinNt/2000. Sbaglio?
--
Ciao.


 Sě, certo, dipende un po' dai gusti: a questo punto forse varrebbe la pena
di implementare il drag/drop
Compito per casa per Sebastiano! ;-)))


 Maurizio
CiaoZ

Ok. Per la settimana prossima implemento il D&D! CiaoZ
Dungeons and Dragons? :)
Al mitin qualcuno si porta il portatile --oltre a me--? :) Giusto per
cercare di rientrare IT :)
Saluti.
-- 
      Gianni "bugbarbeq" Rondinini, 25, RA, 242, 152
  VBR - Vero Birro Romagnolo®, diffidate dalle imitazioni!
 Opel/ECC Calibrezio EVO-IV --- Kawasaki "Gas Gas" ZZ-R 1100
 ICQ# 36893168 - IRCNet: bugbarbeq, @ on #linux-it & #NetBSD