2013-02-25 68 views
1

我使用Delphi 2010,我搜索了互聯網,並找到了一些例子,但他們都沒有工作。我使用它可能是因爲2010和unicode?無論如何......簡單TListView保存並加載文件(僅保存列字符串值)

我正在尋找兩個例程來爲TListView做一個簡單的保存和載入和載入文件。 我只想保存每列中的字符串值。即標題和子項目。我對保存佈局或任何對象不感興趣。

procedure SaveToFile(const FileName: string); 
procedure LoadFromFile(const FileName: string); 
+1

現在你達到了時間的價值時,你就會明白,[你應該保持數據從GUI控件分離](http://stackoverflow.com/questions/15057886/tlistview-column-sort-sort-by-first-two-columns#comment21171040_15057886)。 – TLama 2013-02-25 18:10:37

+0

@TLama是對的,你真的不想讓視覺控制成爲你的主要數據結構。 – 2013-02-25 18:32:26

+0

這只是一個簡單的destop應用程序,它不會持有多於幾百項 – JakeSays 2013-02-25 21:07:22

回答

5

這裏有一些非常粗俗的東西。它使用了一個相當有限的製表符分隔的文本格式。內容不允許包含內聯製表符。我也沒有檢查任何負載函數的錯誤。我相信你可以補充一點。

uses 
    ComCtrls, Types, StrUtils; 

procedure ListViewSaveToFile(ListView: TListView; const FileName: string); 

    procedure AddTextToLine(var Line: string; const Text: string); 
    begin 
    Line := Line + Text + #9; 
    end; 

    procedure MoveCompletedLineToList(const Strings: TStringList; var Line: string); 
    begin 
    Strings.Add(System.Copy(Line, 1, Length(Line)-1));//remove trailing tab 
    Line := ''; 
    end; 

var 
    Strings: TStringList; 
    LatestLine: string; 
    i, j: Integer; 

begin 
    LatestLine := ''; 

    Strings := TStringList.Create; 
    try 
    for i := 0 to ListView.Items.Count-1 do begin 
     AddTextToLine(LatestLine, ListView.Items[i].Caption); 
     for j := 0 to ListView.Items[i].SubItems.Count-1 do begin 
     AddTextToLine(LatestLine, ListView.Items[i].SubItems[j]); 
     end; 
     MoveCompletedLineToList(Strings, LatestLine); 
    end; 
    Strings.SaveToFile(FileName, TEncoding.UTF8); 
    finally 
    Strings.Free; 
    end; 
end; 

procedure ListViewLoadFromFile(ListView: TListView; const FileName: string); 
var 
    Strings: TStringList; 
    i, j: Integer; 
    Fields: TStringDynArray; 
    Item: TListItem; 
begin 
    Strings := TStringList.Create; 
    try 
    Strings.LoadFromFile(FileName); 
    ListView.Clear; 
    for i := 0 to Strings.Count-1 do begin 
     Fields := SplitString(Strings[i], #9); 
     Item := ListView.Items.Add; 
     Item.Caption := Fields[0]; 
     for j := 1 to high(Fields) do begin 
     Item.SubItems.Add(Fields[j]); 
     end; 
    end; 
    finally 
    Strings.Free; 
    end; 
end; 
0

我想出了我自己的解決方案,使用TStringList和名稱/值對,這似乎工作得很好。我存儲在名爲條款標題,並在值所有的子欄目,然後我就分析了各個子項目

procedure LoadFromFile(AListView: TListView; AFileName: string); 
var 
I : Integer; 
SL: TStringList; 
Item: TListItem; 
Col0, Col1, Col2, Col3, Col4, Col5: String; 
begin 
    SL:= TStringList.Create; 
    try 
    SL.LoadFromFile(AFileName); 
    AListView.Items.BeginUpdate; 
    AListView.Items.Clear; 
    for I:= 0 to SL.Count - 1 do 
    begin 
    Item:= AlistView.Items.Add; 
    Item.Caption:= SL.Names[I]; 
    parseValue(SL.ValueFromIndex[I], Col0, Col1, Col2, Col3, Col4, Col5); 
    Item.SubItems.Add(Col0); 
    Item.SubItems.Add(Col1); 
    Item.SubItems.Add(Col2); 
    Item.SubItems.Add(Col3); 
    Item.SubItems.Add(Col4); 
    Item.SubItems.Add(Col5); 
    end; 
    AListView.Items.EndUpdate; 
    finally 
    SL.Free; 
    end; 
end; 

    procedure SaveToFile(AListView: TListView; AFileName: string); 
    var 
    I: Integer; 
    SL: TStringList; 
    begin 
    SL:= TStringList.Create; 
    for I := 0 to AListView.Items.Count - 1 do 
    begin 
     SL.Add(AlistView.Items[I].Caption + '=' + 
      AlistView.Items[I].SubItems[0] + ',' + 
      AlistView.Items[I].SubItems[1] + ',' + 
      AlistView.Items[I].SubItems[2] + ',' + 
      AlistView.Items[I].SubItems[3] + ',' + 
      AlistView.Items[I].SubItems[4] + ',' + 
      AlistView.Items[I].SubItems[5]) 
    end; 
    try 
     SL.SaveToFile(AFileName); 
    finally 
     SL.Free; 
    end; 
    end; 

procedure parseValue(AValue: String; var Col0, Col1, Col2, Col3, Col4, Col5: String); 
var 
    I: Integer; 
    S: String; 
    L: TStringList; 
begin 
    //create a temporary list to store the data parts in 
    L:= TStringList.Create; 
    try 
    //iterate through the length of the string 
    for I:= 1 to length(AValue) do 
    begin 
    //if the char is not a comma, append it to S 
    if AValue[I] <> ',' then 
    S:= S + AValue[I] 
    else 
    // if char is a comma, add S to temporary list and reset S 
    begin 
    L.Add(S); 
    S:= ''; 
    end; 
    end; 
    //add the last string to temporary list 
    L.Add(S); 
    //assign the items in temporary list to variables to be passed back 
    Col0:= L[0]; 
    Col1:= L[1]; 
    Col2:= L[2]; 
    Col3:= L[3]; 
    Col4:= L[4]; 
    Col5:= L[5]; 
    finally 
    L.Free; 
    end; 
end; 
+1

當您更改列數時,您將要做什麼。你不應該硬編碼。爲什麼重新發明SplitString。 – 2013-02-25 22:00:40

+1

我沒有改變列的數量,我不知道拆分字符串。我會用你的解決方案,我只是想看看我能否自己寫點東西。學習 – JakeSays 2013-02-25 23:38:50

+0

沒有probs。雖然你的解決方案非常好!不要誤解我的意思。我提出的批評有希望具有建設性。不要忘記添加錯誤檢查,儘管用戶在保存和加載之間已經混淆了文件的內容。 – 2013-02-26 09:45:55