2011-07-31 138 views
2

我試圖排序標籤的值。我有很多帶有整數值的標籤。標籤被稱爲Label1,Label2,[...],Im通過FindComponent訪問。我在存儲在數組中的整數值排序時沒有問題,但問題是,排序後,我不知道哪個標籤具有什麼價值。我的目標是喜歡根據它們的值對這些標籤進行排序,這樣我就可以像使用按值排序的標籤一樣獲得數組。林停留在這一點:( 如:德爾菲標籤值排序

Label1.Caption := 10; 
Label2.Caption := 4; 
Label3.Caption := 7; 

for i := 1 to 3 
do some_array[i] := StrToInt(TLabel(FindComponent('Label' + IntToStr(i))).Caption); 

sortarray(some_array); 

現在,我已經整理排列,但是我缺乏這將也是在相應的地方商店的標籤數量可有人點我了

回答

1
某種程序?

而不是創建一個整數數組的,創造的TLabel控件數組。這一次,你可以順便爲整數數組相同的排序。事實上,給定一個MyLabel: TLabel,你可以很容易地獲得相關的整數StrToInt(MyLabel.Caption)

另外,FindComponent方法不是非常有效。我會做

const 
    ALLOC_BY = 100; 
    MAGIC_TAG = 871226; 
var 
    i: Integer; 
    ActualLength: integer; 
    FLabels: array of TLabel; 
begin 
    SetLength(FLabels, ALLOC_BY); 
    ActualLength := 0; 
    for i := 0 to ControlCount - 1 do 
    if Controls[i] is TLabel then 
     with TLabel(Controls[i]) do 
     if Tag = MAGIC_TAG then 
     begin 
      if ActualLength = length(FLabels) then 
      SetLength(FLabels, length(FLabels) + ALLOC_BY); 
      FLabels[ActualLength] := Controls[i]; 
      inc(ActualLength); 
     end; 
    SetLength(FLabels, ActualLength); 

    SortArray(FLabels) // with respect to the StrToInt(CurLabel.Caption) of each 
        // CurLabel: TLabel. 

當然,你可以跳過塊分配,如果你知道標籤的數量提前。

確保要包含在陣列中的每個標籤的Tag設置爲MAGIC_TAG

另一種選擇是創建一個數組

FLabelDataArray: array of TLabelData; 

type 
    TLabelData = record 
    Control: TLabel; 
    Value: integer; 
    end; 

其中

FLabelDataArray[i].Value := StrToInt(FLabelDataArray[i].Control.Caption); 

被計算一次。

+2

我是唯一一個認爲排序標籤是無稽之談的人嗎?標籤不應該用於存儲,IMO。一個應該使用真正的存儲(如數組或TList )並對其進行排序。 –

+0

@Rudy:我完全同意。但我被給了這個問題,所以我回答了。我能做的事情不多。 –

+0

看到我的答案。人們可以學習。

0

正如Andreas所說,把標籤放入一個動態數組中,而不是對數值進行排序。一旦這種陣列中有他們,對它們進行排序是這樣的:

uses 
    Generics.Defaults, Generics.Collections; 

procedure SortLabels(var Labels: array of TLabel); 
var 
    Comparison: TComparison<TLabel>; 
    Comparer: IComparer<TLabel>; 
begin 
    Comparison := function(const Left, Right: TLabel): Integer 
    begin 
     Result := StrToInt(Left.Caption)-StrToInt(Right.Caption); 
    end; 
    Comparer := TDelegatedComparer<TLabel>.Create(Comparison); 
    TArray.Sort<TLabel>(Labels, Comparer); 
end; 
+0

我使用delphi 7;不能找到仿製藥:( – Klemik

+0

沒有仿製藥在d7 –

1

快速正骯髒的解決方案,也能在老德爾福版本,就是用TStringList,其中有一個Sort方法和Objects財產允許您將一個對象與列表中的每個條目相關聯。

請注意,列表按字典順序排序,所以整數在轉換爲字符串時必須用零填充。

var 
    list: TStringList; 
    i: integer; 
    lab: TLabel; 
begin 
    Label1.Caption := '10'; 
    Label2.Caption := '4'; 
    Label3.Caption := '7'; 

    list := TStringList.Create; 
    try 
    for i := 1 to 3 do begin 
     lab := TLabel(FindComponent('Label' + IntToStr(i))); 
     list.AddObject(Format('%10.10d', [StrToInt(lab.Caption)]), lab); 
    end; 

    list.Sort; 

    for i := 0 to list.Count-1 do 
     Memo1.Lines.Add(list[i] + #9 + TLabel(list.Objects[i]).Name); 
    finally 
    list.Free; 
    end; 
end; 

輸出將是:

0000000004 Label2 
0000000007 Label3 
0000000010 Label1 

而且,如果不是list.Sort您使用list.Sorted := true,你會得到list作爲獎金二進制搜索(使用list.IndexOflist.Find)。

編輯:作爲魯迪說,可視化組件如TLabel應該只用於顯示數據,而不能用於存儲和操作它。建議爲此使用適當的數據結構,並將程序的邏輯與其用戶界面分開。

+0

這對我工作最好;謝謝 – Klemik

+0

@Klemik如果這是最好的答案,那麼請考慮接受它。 COM /問題/ 5234 /如何-不接受-的回答工作 –

0

正如其他人所說,我不認爲你正在採取正確的方法來完成這項任務。但是,根據您的問題,一個簡單的黑客會使用每個標籤上的標籤屬性來存儲它的標題值:

Label1.Caption := '10'; 
Label1.Tag:=10; 
Label2.Caption := '4'; 
Label2.Tag:=4; 
Label3.Caption := '7'; 
Label3.Tag := 7; 

然後你就可以與入門「整數數組」匹配找到合適的標籤標籤的標籤屬性。

還是那句話:隨着魯迪和其他人評論說,你的方法把這個任務還遠遠沒有希望的,我的解決方案不僅符合你的方法。標籤屬性本身是德爾福內置的一種黑客技術,它是古代的一種神器,比如'label'和'goTo',真的不應該使用,除非絕望 - 比如當試圖重新工作和復古適合古代,寫得不好的代碼,或者如果你有刺激的東西,你必須快速解決緊急情況。