2011-04-26 37 views
0

我想知道如何在創建的列表中獲得某個對象的位置。 可以說它就像一個圖形列表,您可以點擊對象。 讓我們說你右鍵單擊一個對象,然後單擊「刷新」,我如何獲得該對象的位置,以便在整個列表刷新後(由於某種原因刷新清單),我回到同一個位置清單?這是如果列表說1000個對象長,這使得刷新後嘗試向下滾動到相同位置是麻煩的。在Delphi中獲取列表中對象的位置?

該代碼使用Tobject,但我可以做些什麼,如 position:= integer(TObject。「pointerinfo ???」); 然後,當程序刷新 就像設置視圖的位置像指針 像currentview(指針)或類似的東西?

實際上它不一定是同一個對象,但列表的相同「視圖」會更好。

在此先感謝

+1

你在找'TListItem.Index'嗎?你失去了我的位置:=整數(TObject。「pointerinfo ????」);' – 2011-04-26 12:53:33

+2

什麼是「圖形列表」和「對象」?您嘗試使用哪些課程?你能展示代碼示例嗎? – Andrew 2011-04-26 13:11:36

回答

1

所以我覺得在我得到的幫助下,我回答了我自己的問題。 我所做的就是編寫一些需要使用listview的x和y位置的內容,稍後使用clearlist進行刷新後,我使用滾動函數返回相同的函數。我的程序看起來像這樣。

procedure Refresh(Sender: TObject); 
var 
    horzpos:integer; 
    vertpos:integer; 
begin 
    horzpos:=ListView1.ViewOrigin.X; 
    vertpos:=ListView1.ViewOrigin.Y; 
    RefreshListView(ListView1); //A function that refreshes the list and clears it 
    ListView1.Scroll(horzpos, vertpos); 
end; 

也許我應該在前面說過這是一個listview類型,我希望在「清單」之後再次回到相同的位置。

感謝所有的幫助,這個社區的岩石!

4

如果耳目一新會再次給你相同的名單,並以相同的順序,那就不必發現關於對象的任何東西。只需存儲列表控件的ItemIndex屬性,該屬性指示當前選定的項目。

如果刷新可能會給你一個不同的列表,那麼你想要的對象可能不在同一個位置,所以只記得ItemIndex是不夠的。在這種情況下,您需要找到對象的新位置。如何做到這一點取決於列表控件的功能以及它如何公開與每個位置關聯的對象。例如,如果您有一個TListBox,則Items屬性爲TStrings對象,並且您可以檢查Objects數組的每個值,直到找到所需的對象。存儲對象引用的值,然後搜索該值。類似這樣的:

procedure Refresh; 
var 
    CurrentSelection: TObject; 
    ObjectPosition: Integer; 
    i: Integer; 
begin 
    if List.ItemIndex >= 0 then 
    CurrentSelection := List.Strings.Objects[List.ItemIndex] 
    else 
    CurrentSelection = nil; 
    RefreshList; 
    ObjectPosition := -1; 
    if Assigned(CurrentSelection) then begin 
    for i := 0 to Pred(List.Count) do begin 
     if List.Strings.Objects[i] = CurrentSelection then begin 
     ObjectPosition := i; 
     break; 
     end; 
    end; 
    end; 
    if ObjectPosition = -1 then 
    // Object isn't in refreshed list 
    else 
    // It is. 
end; 

最後的可能性是刷新並不實際上保持相同的對象。所有先前的對象都被銷燬,並且生成一個新的對象列表。在這種情況下,您必須記住原始對象的某些識別特徵,以便可以找到代表相同內容的新對象。事情是這樣的:

var 
    CurrentObject, Person: TPerson; 
    CurrentName: string; 
    i, ObjectPosition: Integer; 
begin 
    if List.ItemIndex >= 0 then begin 
    CurrentObject := List.Strings.Objects[List.ItemIndex] as TPerson; 
    CurrentName := CurrentObject.Name; 
    end else 
    CurrentName = ''; 
    RefreshList; 
    ObjectPosition := -1; 
    if CurrentName <> '' then begin 
    for i := 0 to Pred(List.Count) do begin 
     Person := List.Strings.Objects[i] as TPerson; 
     if Person.Name = CurrentName then begin 
     ObjectPosition := i; 
     break; 
     end; 
    end; 
    end; 
    if ObjectPosition = -1 then 
    // Object isn't in refreshed list 
    else 
    // It is. 
end; 

在所有這些情況下,你應該認識到該對象在列表中的位置是不實際的對象的屬性。相反,它是列表的屬性,這就是爲什麼列表在所有代碼中扮演比對象更重要的角色的原因。實際上並沒有任何「指針信息」可以從對象中獲取,因爲對象通常不知道它甚至不在列表中,所以它肯定不會知道它相對於列表中的所有其他項的位置。

確定對象在列表中的位置後,需要將其滾動到視圖中。對於TListBox,一個簡單的方法就是設置其屬性TopIndex

List.TopIndex := ObjectPosition; 

最後,如果你不真正關心當前對象所有,但只是要恢復當前滾動位置,那麼這更容易:

procedure Refresh; 
var 
    CurrentPosition: Integer; 
begin 
    CurrentPosition := List.TopIndex; 
    RefreshList; 
    List.TopIndex := CurrentPosition; 
end; 
+0

TStrings類實際上有一個'IndexOfObject'方法,它可以更快地找到對象(只要對象地址沒有改變)。在較新版本的Delphi中,TObject具有Equals方法,可以方便地進行等式比較,通過重寫此方法,等式代碼可以保存(封裝)在類定義中。 – mjn 2011-04-26 14:54:09

+0

非常感謝您的幫助! 我試圖做的是你的最後一個命令行,但由於某種原因它說我無法構建它,因爲:E2129無法分配給只讀屬性。 這是代碼: var currentposition:integer; 開始 當前位置:= Lvproxy.CurrentListView.TopItem.Index; RefreshListView(LVProxy.CurrentListView); LVProxy.CurrentListView.TopItem.Index:= Currentposition; 我可以看到它得到正確的位置和所有,但我不能使用該值並插入當前listview由於只讀屬性,無論如何解決這個問題? – Joe 2011-04-26 15:08:51

+0

喬,你的代碼試圖設置哪個項目恰好位於視口頂部的索引。設置對象的索引(如果允許的話)將*移動列表*中的項目,而不是滾動視口。要滾動「TListView」的視口,請使用其「Scroll」方法。或者在'TListItem'上調用'MakeVisible'。 – 2011-04-26 16:06:39