2012-01-26 20 views
8

Poniższy kod ładnie ożywia dodając nowy ciąg do końca ListBoxAnimowanie dodanie napisu do ListBox w 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; 

Element rozszerza się i zanika w. Jednak chcę, aby móc dodaj ciąg do dowolnej lokalizacji w polu ListBox - faktycznie w bieżącym ItemIndex. Czy ktoś wie, jak to zrobić?

Odpowiedz

4

Aby obejść fakt, że ListBox1.InsertObject i ListBox1.Items.Insert nie działają można wykonać następujące czynności

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; 

ale jest nieco śmieszne. To (ewentualnie) dodaje ciąg w pozycji 0, jeśli nie ma wybranego elementu, w przeciwnym razie dodaje go przed wybranym elementem. To rozwiązanie zbyt mocno przypomina mi Bubble Sort. Będziesz musiał dodać jednostkę matematyczną do swojej klauzuli uses, aby funkcja max działała.

To rzeczywiście wygląda na błąd w FireMonkey (sprawdź Quality Central #102122), ale podejrzewam, że przyszła aktualizacja FireMonkey to naprawi. Jeśli ktokolwiek może zobaczyć lepszy sposób na zrobienie tego ...

Mam również o tym made a movie o tym dla zainteresowanych, który ilustruje sprawy jaśniej.

+0

Działa dobrze. Tasowanie listy jest dość szybkie, chyba że masz bardzo dużą listę. –

0

Zamiast

l.Parent := ListBox1; 

użytku

ListBox1.InsertObject(Index, l); 

gdzie Index jest położenie wstawienia.

(Niewygodne, ale z powodu czytania źródeł, które powinno działać).

+1

ListBox1.InsertObject (0, l) nie działa i daje naruszenie zasad dostępu, chociaż jeśli usunę kod związany z animacją, wartość listbox1.count wzrośnie, ale nic nie zmieni się w widoczny sposób. ListBox1.AddObject (l) działa dobrze (chociaż daje taki sam wynik jak mój oryginalny kod). – Alister

2

To powinno działać, ale to nic nie robi:

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

Gdybym wtedy zadzwonić pod następujące otrzymuję naruszenie zasad dostępu:

ListBox1.Realign; 

W rzeczywistości, nawet ta daje mi AV:

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

Ale dodaje, oczywiście:

ListBox1.Items.Add('hello'); 

Może błąd?

+0

Tak, otrzymuję ten sam wynik - Zgadzam się - prawdopodobnie błąd – Alister

+0

Jak wspomniano powyżej, Listbox.items.Insert jest obecnie uszkodzony. Może naprawisz aktualizację 4? –