2007. március 7., szerda
Save and load TListView items to / from a file
Problem/Question/Abstract:
I would like to know how to save TListView items and subitems into a file and reload them into the listview on a button click or the next time the program starts.
Answer:
Solve 1:
The answer depends on what information you need to save and restore: only the strings or also image indices, if the latter, which indices? If it's only the strings one could do it this way:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ComCtrls,
StdCtrls;
type
TForm1 = class(TForm)
ListView1: TListView;
SaveButton: TButton;
ClearButton: TButton;
LoadButton: TButton;
procedure ClearButtonClick(Sender: TObject);
procedure SaveButtonClick(Sender: TObject);
procedure LoadButtonClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
{
Function IScan:
Parameters:
ch: Character to scan for
S : String to scan
fromPos: first character to scan
Returns: position of next occurence of character ch, or 0, if none found
Description: Search for next occurence of a character in a string
Error Conditions: none
Created: 11/27/96 by P. Below
}
function IScan(ch: Char; const S: string; fromPos: Integer): Integer;
var
i: Integer;
begin
Result := 0;
for i := fromPos to Length(S) do
begin
if S[i] = ch then
begin
Result := i;
Break;
end;
end;
end;
{
Procedure SplitString:
Parameters:
S: String to split
separator: character to use as separator between substrings
substrings: list to take the substrings
Description: Isolates the individual substrings and copies them into the passed stringlist. Note that we only add to the list, we do not clear it first! If two separators follow each other directly an empty string will be added to the list.
Error Conditions: will do nothing if the stringlist is not assigned
Created: 08.07.97 by P. Below
}
procedure SplitString(const S: string; separator: Char; substrings: TStringList);
var
i, n: Integer;
begin
if Assigned(substrings) and (Length(S) > 0) then
begin
i := 1;
repeat
n := IScan(separator, S, i);
if n = 0 then
n := Length(S) + 1;
substrings.Add(Copy(S, i, n - i));
i := n + 1;
until
i > Length(S);
end;
end;
resourcestring
eInvalidViewstyle = '%s: the listview %s is not in vsReport mode.';
{
Procedure SaveListviewStrings:
Parameters :
listview : listview to save, must be in vsreport mode, <> nil
filename : full pathname of file to create
Description:
Iterates over the items of the passed listview and saves the item and
subitem strings to file. The created file is a plain text file, each item
occupies one line, subitems are separated by tab characters.
Error Conditions:
An exception will be raised if the listview is not in vsreport mode or if the
file cannot be written to.
Created: 2.4.2000 by P. Below
}
procedure SaveListviewStrings(listview: TLIstview; const filename: string);
var
sl: TStringlist;
S: string;
i, k: Integer;
item: TLIstItem;
begin
Assert(Assigned(listview));
if listview.ViewStyle <> vsReport then
raise Exception.CreateFmt(eInvalidViewstyle, ['SaveListviewStrings',
listview.name]);
sl := TStringlist.Create;
try
for i := 0 to listview.items.count - 1 do
begin
item := listview.Items[i];
S := item.Caption;
for k := 0 to item.SubItems.Count - 1 do
S := S + #9 + item.Subitems[k];
sl.Add(S);
end;
sl.SaveToFile(filename);
finally
sl.free
end;
end;
{
Procedure LoadListviewStrings:
Parameters :
listview : listview to load, must be in vsreport mode, <> nil
filename : full pathname of file to read
Description:
Reads the file into a stringlist and then dissects each line into another list
of strings. It expects the lists elements to be separated by tab characters. For
each line read a new listitem is added to the listview and its caption and subitems are set from the lines elements. Note that the listview is not cleared
first, so the new items will be added to whatever items the listview already contains.
Error Conditions:
An exception will be raised if the listview is not in vsreport mode or if the file cannot be loaded.
Created: 2.4.2000 by P. Below
}
procedure LoadListviewStrings(listview: TLIstview; const filename: string);
var
sl, lineelements: TStringlist;
i: Integer;
item: TLIstItem;
begin
Assert(Assigned(listview));
if listview.ViewStyle <> vsReport then
raise Exception.CreateFmt(eInvalidViewstyle, ['LoadListviewStrings',
listview.name]);
sl := TStringlist.Create;
try
sl.LoadFromFile(filename);
lineelements := Tstringlist.Create;
try
for i := 0 to sl.count - 1 do
begin
lineelements.Clear;
SplitString(sl[i], #9, lineelements);
if lineelements.Count > 0 then
begin
item := listview.Items.Add;
item.Caption := lineelements[0];
lineelements.Delete(0);
item.SubItems.Assign(lineelements);
end;
end;
finally
lineelements.free;
end;
finally
sl.free
end;
end;
const
testfilename = 'c:\temp\testfile.txt';
procedure TForm1.ClearButtonClick(Sender: TObject);
begin
listview1.items.clear;
end;
procedure TForm1.SaveButtonClick(Sender: TObject);
begin
SaveListviewStrings(listview1, testfilename);
end;
procedure TForm1.LoadButtonClick(Sender: TObject);
begin
LoadListviewStrings(listview1, testfilename);
end;
end.
Solve 2:
Subclass TListView and add these to your new component:
unit MyListView;
interface
uses
SysUtils, Classes, ComCtrls, Forms, Windows, Menus, Controls;
type
TCheckBoxString = class(TComponent)
private
FTheString: string;
protected
public
published
property CheckBoxString: string read FTheString write FTheString;
end;
TMyListView = class(TListView)
private
public
procedure SaveToFile(FileName: string);
procedure LoadFromFile(FileName: string);
published
end;
procedure Register;
implementation
procedure TMyListView.SaveToFile(FileName: string);
var
FStream: TMemoryStream;
i: Integer;
FStrings: TCheckBoxString;
begin
FStream := TMemoryStream.Create;
FStrings := TCheckBoxString.Create(nil);
try
FStream.WriteComponent(Self);
if Self.Checkboxes then
begin
FStrings.CheckBoxString := '';
for i := 0 to Self.Items.Count - 1 do
begin
if Self.Items[i].Checked then
FStrings.CheckBoxString := FStrings.CheckBoxString + 'T'
else
FStrings.CheckBoxString := FStrings.CheckBoxString + 'F';
end;
FStream.WriteComponent(FStrings);
end;
FStream.SaveToFile(FileName);
finally
FStream.Free;
FStrings.Free;
end;
end;
procedure TMyListView.LoadFromFile(FileName: string);
var
FStream: TFileStream;
i: Integer;
FStrings: TCheckBoxString;
begin
FStream := TFileStream.Create(FileName, fmOpenRead);
FStrings := TCheckBoxString.Create(nil);
try
Self.Columns.BeginUpdate;
Self.Items.BeginUpdate;
Self.Items.Clear;
Self := FStream.ReadComponent(Self) as TMyListView;
if Self.Checkboxes then
begin
FStrings := FStream.ReadComponent(FStrings) as TCheckBoxString;
for i := 0 to Self.Items.Count - 1 do
begin
if (i + 1) <= Length(FStrings.CheckBoxString) then
Self.Items[i].Checked := (FStrings.CheckBoxString[i + 1] = 'T');
end;
end;
finally
FStream.Free;
FStrings.Free;
Self.Columns.EndUpdate;
Self.Items.EndUpdate;
end;
end;
Feliratkozás:
Megjegyzések küldése (Atom)
Nincsenek megjegyzések:
Megjegyzés küldése