2011-11-11 59 views
3

在德爾福中,是否有一種快速清空TStringgrid(包含超過5000行)的方法,還可以釋放內存?清空Delphi中的字符串網格

將rowcount設置爲1,清空網格但不釋放內存。

由於提前,

保羅

+0

內存有什麼問題?將rowcount設置爲1不會釋放內存,但根據我的說法,當您重新填充行時,會再次使用此內存。如果你真的想釋放內存,請釋放TStringGrid並重新創建它。 – philnext

回答

10

這應該取消初始化分配的字符串(從其中行的文本存儲的字符串列表)。由於您有很多行,所以清理工作由列完成。

procedure TForm1.Button1Click(Sender: TObject); 
var 
    I: Integer; 
begin 
    for I := 0 to StringGrid1.ColCount - 1 do 
    StringGrid1.Cols[I].Clear; 
    StringGrid1.RowCount := 1; 
end; 
+1

這樣做的伎倆 - 非常感謝 –

4

通過「不釋放內存」,你的意思是,如果你設置RowCount := 1,然後設置RowCount := 10' you can still see the old content of the Cells`?

如果是這樣,這是一個老問題,並且與沒有被釋放的內存無關;這僅僅是因爲當你再次分配內存時你碰巧看到了先前的內存內容,因爲內存不是零。

我在處理這種視覺故障的實用單元中有一個非常標準的例程,除非網格是巨大的工作得足夠快。只需在之前通過TStringGrid即可將RowCountColCount更改爲較低的值。

procedure ClearStringGrid(const Grid: TStringGrid); 
var 
    c, r: Integer; 
begin 
    for c := 0 to Pred(Grid.ColCount) do 
    for r := 0 to Pred(Grid.RowCount) do 
     Grid.Cells[c, r] := ''; 
end; 

使用方法如下:

ClearStringGrid(StringGrid1); 
StringGrid1.RowCount := 1; 
+0

反過來也不會更好嗎?首先設置'RowCount'然後'ClearStringGrid'?你沒有通過'BeginUpdate' /'EndUpdate'鎖定更新,它可能會閃爍。 – TLama

+1

其實沒有。 :)如果先更改'RowCount',則無法訪問舊行以清除它們。你說對了,但忘了'Begin/EndUpdate';我的實際代碼在不同的機器上,我忘了它們。固定。 :) –

+0

沒有'TStringGrid.BeginUpdate'或'TStringGrid.EndUpdate';)但是你可以訪問'行'或'Cols',因爲OP說他有很多行我決定清除Cols。當然你是對的,如果你先設置'RowCount',那麼你只需迭代一次。 – TLama

2

的最快方式使用TStringGrid使用OnGetValue/OnSetValue。 這種方式只能動態地請求可見單元格的文本。 添加和刪除行然後點亮得很快,否則當您有超過5000條記錄時,TStringgrid是 非常單薄。 通過這種方式,我可以在一秒鐘內填寫並清除700.000條記錄中的網格!

4

我建議將字符串值存儲在您自己的內存中,您可以完全控制它,然後使用TDrawGrid或更好的虛擬TListView根據需要顯示該內存的內容。

+0

+1或我最喜歡的[VirtualTreeView](http://code.google.com/p/virtual-treeview/source/browse/#svn%2Ftrunk):) – TLama

1

當內存使用率是關鍵參數時,請考慮使用另一個網格。例如,NLDStringGrid由我自己寫(重新),並且有一個名爲MemoryOptions的附加屬性。它控制數據是否可以存儲在ColCount * RowCount之外,存儲是否成比例(部分填充的行和列的內存使用量較少),是否存儲ColsRows屬性結果以及是否以稀疏方式存儲數據。

要清除此類網格,其中moBeyondGrid排除在內存選項之外,則只需將RowCount設置爲FixedRows即可。

它的開源和可下載from here