views:

367

answers:

5

hi all

I want to write an app that uses a Access database (*.mdb). I know how to connect to a mdb and how to use SQL statements. My problem is that I want to put the result of a query into a TListView.

Any info/link/book is welcomed :)

+2  A: 

TListView is not a data-aware component, and there isn't (AFAIK) a VCL TDBListView - if you need a grid of data, you can either bind to a TDBGrid, or use a 3rd part TDBListView, which you can find with a quick google.

Ben Laan
I thought that I can read the data from the table and insert it to a ListView
Remus Rigo
Yes you can do that. But Delphi has data aware controls that access to any database table or query you like.
Gamecat
@Remus, Gamecat is right. You are free of course to loop the dataset, build a list of objects which map the column structure, and then populate the listview by binding the object properties for each item in the list into the listview. Is this the approach you are interested in? If you prefer this approach, you should use something like tiOPF or equivalent, it does all this for you.
Ben Laan
Depending on who you ask, database aware controls are evil. But at least you should know that they exist and what advantages and disadvantages they have.
dummzeuch
+1  A: 

You can either add each record to a TListView. Just looping through the records and put the contents of the fields into the required control.

But Delphi provides data aware controls. That take care of the database connection. For most applications this is enough.

Gamecat
+3  A: 

Pull your result and then pass it to the following procedure (for example):

Query.First;
While not Query.EOF do
  begin
    StrObj := tStringList.create;
    StrObj.Add(Query.FieldByname('id').asString);
    ListView.AddItem(Query.FieldByName('Title').AsString,StrObj);
    Query.Next;
  end;

This will load your list view with nodes named by the fieldname title, and each node will contain a tstringlist containing whatever data you want to store for each node. Personally I would extend this and use a custom holder object rather than the tStringList, but this was just an example.

skamradt
Make sure to call Query.First before this loop...
Mason Wheeler
+1  A: 

There are some implementations of VirtualTreeView that work with databases. Here's one link, and here is VirtualTreeView web site.

Mihaela
TreeView and ListView are different controls.
Larry Lustig
I was aware of that. There is an implementation of Virtual ListView by Mustang Peak Software @ http://www.mustangpeak.net/.
Mihaela
+2  A: 

Using a ListView to represent a disconnected set of data is my favorite design pattern with Delphi database applications. The ListView control offers several different display formats of which vsReport is the one that looks like a table of data with rows and columns (the others are vsList, vsIcon, and vsLargeIcon).

To create "items" (which map to rows, at least when vsReport is the display style) you call AddItem() on the ListView's Items collection. AddItem will return an object of type TListItem. You can assigne a Caption to the item which becomes the description (in vsList, vsIcon, and vsLargeIcon styles) and the first column of the "table" in vsReport. The list item also has a TStringList property called SubItems. Each string added to SubItems will provide data for another column in vsReport mode (the SubItems are ignored in the other modes).

Finally, if you want to associate an integer primary key value back to your original database record you can do this using the TListItem's Data member. This is a pointer to an object associated with the item, but you can cast an integer and store it away there.

So, for instance:

DS := TSomeKindOfDataSet.Create();

try

    //Set up and open DS.

    while not DS.eof do begin

        with ListView.Items.Add() do begin

            //establish three columns for vsReport display
            Caption := DS.FieldByName('DescriptiveField').AsString;
            SubItems.Add(DS.FieldByname('AnotherColumn').AsString);
            SubItems.Add(DS.FieldByname('YetAnotherColumn').AsString);

            //Save the record's PK value
            Data := Pointer(DS.FieldByname('PKColumn').AsInteger);

        end;

        DS.Next;

    end;

finally

   DS.Free;

end;

This gives you a list view containing the data from DS, along with the primary key value so that you can locate any record the user selects in the list view. DS is closed and disposed of while the user is working with the list view, so there's no ongoing demand on the database.

Larry Lustig