Question

My code is the below, it's working correctly but, but after compiling program i see all the fullname and country listed vertically something like :

_________________________________
Fullname1
Country1
Fullname2
Country2
Fullname3
Country3
etc...

SQLQuery1.SQL.Text := 'SELECT * FROM users where user_age="'+age+'"';
SQLQuery1.Open;
rec := SQLQuery1.RecordCount;

SQLQuery1.First; // move to the first record
ListView1.Visible := false;
if rec>0 then
begin
while(not SQLQuery1.EOF)do begin
ListView1.Visible := true;
        // do something with the current item
ListView1.AddItem('Full name: '+SQLQuery1['fullname'], Self);
ListView1.AddItem('Country: '+SQLQuery1['cntry'], Self);

    // move to the next record

SQLQuery1.Next;

end;

But i want something Like :

enter image description here

Was it helpful?

Solution

First: add the column headers:

var
  Col: TListColumn;
begin
  Col := ListView1.Columns.Add;
  Col.Caption := 'Name';
  Col.Alignment := taLeftJustify;
  Col.Width := 140;

  Col := ListView1.Columns.Add;
  Col.Caption := 'Country';
  Col.Alignment := taLeftJustify;
  Col.Width := 140;
end;

then add the records as follows:

var
  Itm: TListItem;
begin
    // start of your query loop
    Itm := ListView1.Items.Add;
    Itm.Caption := SQLQuery1['fullname'];
    Itm.SubItems.Add(SQLQuery1['cntry']);
    // end of your query loop
end;

Update:

Of course, in order to get the list as in your screenshot, you need to set the ListView's ViewStyle property to vsReport

OTHER TIPS

Your code should look like that:

var
  ListItem: TListItem;

  ...

  ListView.Items.BeginUpdate;
  try
    while(not SQLQuery1.EOF)do begin
      ListItem:= ListView.Items.Add;
      ListItem.Caption:= 'Full name: '+SQLQuery1['fullname'];
      with ListItem.SubItems do begin
        Add('Country: '+SQLQuery1['cntry']);
// if you need more columns, add here
      end;
      SQLQuery1.Next;
    end;
  finally
    ListView.Items.EndUpdate;
  end;

You should also set ListView.Style to vsReport to show listview as grid.

I'm not sure how to get the listview to multiline, but I do know you're not using the Query correctly. As it stands your code has an SQL-injection hole and the implicit reference to 'fieldbyname' inside the loop makes it slow.

var
  FullName: TField;
  Country: TField;
  ListItem: TListItem;
begin
  //Use Params or suffer SQL-injections
  SQLQuery1.SQL.Text := 'SELECT * FROM users where user_age= :age';
  SQLQuery1.ParamByName('age').AsInteger:= age;
  SQLQuery1.Open;
  if SQLQuery1.RecordCount = 0 then Exit;
  //Never use `FieldByName` inside a loop, it's slow.
  FullName:= SQLQuery1.FieldByName('fullname');
  Country:= SQLQuery1.FieldByName('cntry');
  ListView1.Style:= vsReport;

  SQLQuery1.First; // move to the first record
  SQLQuery1.DisableControls; //Disable UI updating until where done.
  try
    ListView1.Items.BeginUpdate;
    //ListView1.Visible := false;
    while (not SQLQuery1.EOF) do begin
      //Code borrowed from @Serg
      ListItem:= ListView.Items.Add;
      ListItem.Caption:= 'Full name: '+Fullname.AsString;
      ListItem.SubItems.Add('Country: '+Country.AsString);
      SQLQuery1.Next;  
    end; {while}
  finally
    SQLQuery1.EnableControls;
    ListView1.Items.EndUpdate;
  end;
end;

The Delphi documentation contains this example that does exactly what you want.

procedure TForm1.FormCreate(Sender: TObject);
const
  Names: array[0..5, 0..1] of string = (
    ('Rubble', 'Barney'),
    ('Michael', 'Johnson'),
    ('Bunny', 'Bugs'),
    ('Silver', 'HiHo'),
    ('Simpson', 'Bart'),
    ('Squirrel', 'Rocky')
    );

var
  I: Integer;
  NewColumn: TListColumn;
  ListItem: TListItem;
  ListView: TListView;
begin
  ListView := TListView.Create(Self);
  with ListView do
  begin
    Parent := Self;
    Align := alClient;
    ViewStyle := vsReport;

    NewColumn := Columns.Add;
    NewColumn.Caption := 'Last';
    NewColumn := Columns.Add;
    NewColumn.Caption := 'First';

    for I := Low(Names) to High(Names) do
    begin
      ListItem := Items.Add;
      ListItem.Caption := Names[I][0];
      ListItem.SubItems.Add(Names[I][2]);
    end;
  end;
end;

For all that the Delphi documentation is much maligned, it often has very useful examples like this. The gateway page to the examples is here and the examples are even available on sourceforge so you can check them out using your favourite svn client.

Procedure TForm1.GetUsers;
var
  ListItem: TListItem;
begin
  try
    ListView1.Items.BeginUpdate;
    try
      ListView1.Clear;
      MySQLQuery.SQL.Clear;
      MySQLQuery.SQL.Add('select * from users;');
      MySQLQuery.Open;
      while (not MySQLQuery.EOF) do
      begin
        ListItem := ListView1.Items.Add;
        ListItem.Caption:= VarToSTr(MySQLQuery['username']);
        with ListItem.SubItems do
          begin
            Add(VarToSTr(MySQLQuery['password']));
            Add(VarToSTr(MySQLQuery['maxscore']));
          end;
        MySQLQuery.Next;
      end;
      MySQLQuery.Close;
    finally
      ListView1.Items.EndUpdate;
    end;
  except
    on E: Exception do
        MessageDlg(PWideChar(E.Message), TMsgDlgType.mtError, [TMsgDlgBtn.mbOK], 0);
  end;
end;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top