首页  编辑  

点击鼠标获取ListView的列

Tags: /超级猛料/VCL/ListView/   Date Created:

Extended GetItemAt

This method (GetItemAt) only provides the information about which ListItem (if any) is located at the specified coordinates passed as parameters, but only works with the first column of the TListView. The rest are ignored. If we needed to know if the user clicked on an element in another column, we can declare a new method in a derived class:

uses ComCtrls;

type

 TListViewX = class(TListView)

 public

   function GetItemAtX(X, Y: integer; var Col: integer): TListItem;

 end;

implementation

function TListViewX.GetItemAtX(X, Y: integer;

   var Col: integer): TListItem;

var

 i, n, RelativeX, ColStartX: Integer;

 ListItem: TlistItem;

begin

 Result := GetItemAt(X, Y);

 if Result <> nil then begin

   Col := 0; // First column

 end else if (ViewStyle = vsReport)

     and (TopItem <> nil) then begin

   // First, let's try to find the row

   ListItem := GetItemAt(TopItem.Position.X, Y);

   if ListItem <> nil then begin

     // Now let's try to find the Column

     RelativeX := X-ListItem.Position.X-BorderWidth;

     ColStartX := Columns[0].Width;

     n := Columns.Count - 1;

     for i := 1 to n do begin

       if RelativeX < ColStartX then break;

       if RelativeX <= ColStartX +

           StringWidth(ListItem.SubItems[i-1]) then

       begin

         Result := ListItem;

         Col := i;

         break;

       end;//if

       Inc(ColStartX, Columns[i].Width);

     end;//for

   end;//if

 end;//if

end;

Casting to the new class

We don't need to intall this new component and register it in the components palette as we explained in another article. Instead, any time we want to access this method, we can just cast the object (for example ListView1) to our new class. For example in a MouseDown event:

procedure TForm1.ListView1MouseDown(Sender: TObject;

 Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

var

 col: integer;

 li: TListItem;

begin

 li := TListViewX(ListView1).GetItemAtX(x, y, col);

 if li <> nil then

   ShowMessage('Column #' + IntToStr(col));

end;