2013-02-25 38 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