2012-01-26 15 views
8

Il seguente codice di ben animato dalla aggiunta di una nuova stringa alla fine di un ListBoxAnimare l'aggiunta di una stringa in un ListBox in FireMonkey

procedure TForm6.AddItem(s: string); 
var 
    l : TListBoxItem; 
    OldHeight : Single; 
begin 
    l := TListBoxItem.Create(Self); 
    l.Text := s; 
    OldHeight := l.Height; 
    l.Height := 0; 
    l.Parent := ListBox1; 
    l.Opacity := 0; 
    l.AnimateFloat('height', OldHeight, 0.5); 
    l.AnimateFloat('Opacity', 1, 0.5); 
end; 

La voce si espande e si affievolisce. Tuttavia voglio essere in grado di aggiungi la stringa in una posizione arbitraria nel ListBox - in realtà nel ItemIndex corrente. Qualcuno sa come fare questo?

risposta

4

Per aggirare il fatto che ListBox1.InsertObject e ListBox1.Items.Insert non funzionano è possibile effettuare le seguenti operazioni

procedure TForm1.AddItem(s: string); 
var 
    l : TListBoxItem; 
    OldHeight : Single; 
    I: Integer; 
    index : integer; 
begin 
    l := TListBoxItem.Create(nil); 
    l.Text := s; 
    OldHeight := l.Height; 
    l.Height := 0; 
    l.Opacity := 0; 
    l.Index := 0; 
    l.Parent := ListBox1; 

    Index := Max(0, ListBox1.ItemIndex); 
    for I := ListBox1.Count - 1 downto Index + 1 do 
    begin 
    ListBox1.Exchange(ListBox1.ItemByIndex(i), ListBox1.ItemByIndex(i-1)); 
    end; 
    ListBox1.ItemIndex := Index; 
    l.AnimateFloat('height', OldHeight, 0.5); 
    l.AnimateFloat('Opacity', 1, 0.5); 
end; 

ma è un po 'ridicolo. Aggiunge (eventualmente) la stringa nella posizione 0 se non è selezionata alcuna voce, altrimenti la aggiunge prima dell'elemento selezionato. Questa soluzione mi ricorda troppo lo Bubble Sort. Sarà necessario aggiungere l'unità matematica alla clausola use per far funzionare la funzione max.

Questo sembra essere un bug in FireMonkey (controllare Quality Central #102122), tuttavia sospetto che un aggiornamento futuro di FireMonkey risolverà questo problema. Se qualcuno può vedere un modo migliore di farlo ...

Ho anche questo articolo per coloro che sono interessati, che illustra le cose in modo più chiaro.

+0

Funziona bene. Mischiare la lista è piuttosto veloce a meno che tu non abbia una lista molto grande. –

0

Invece di

l.Parent := ListBox1; 

uso

ListBox1.InsertObject(Index, l); 

dove N è la posizione di inserimento.

(Non verificato, ma dalla lettura delle fonti dovrebbe funzionare).

+1

ListBox1.InsertObject (0, l) non funziona e fornisce una violazione di accesso, sebbene se rimuovo il codice correlato all'animazione, il listbox1.count aumenta ma nulla cambia visibilmente. ListBox1.AddObject (l) funziona comunque (sebbene fornisca lo stesso risultato del mio codice originale). – Alister

2

Questo dovrebbe funzionare, ma non fa nulla:

l := TListBoxItem.Create(ListBox1); 
ListBox1.InsertObject(Max(ListBox1.ItemIndex, 0), l); 

Se poi chiamare il seguente, ottengo una violazione di accesso:

ListBox1.Realign; 

In realtà, anche questo mi dà un AV:

ListBox1.Items.Insert(0, 'hello'); 
ListBox1.Realign; 

Ma questo aggiunge, naturalmente:

ListBox1.Items.Add('hello'); 

Un errore?

+0

Sì, sto ottenendo lo stesso risultato - Sono d'accordo - probabilmente un bug – Alister

+0

Come detto sopra, Listbox.items.Insert è attualmente rotto. Forse risolti nell'aggiornamento 4? –