如何在TListView.OnColumnDragged中找到已拖动的列?

时间:2012-08-02 10:24:37

标签: delphi listview drag

OnColumnDragged TListView事件有一个简单的TNotifyEvent类型,因此没有直接的方法可以找到实际拖动到新位置的列。

如何找到拖动的列?

2 个答案:

答案 0 :(得分:2)

借助插入的类,您可能会在HDN_ENDDRAG消息处理程序中捕获WM_NOTIFY通知代码。

HDN_ENDDRAG通知在lParam参数中返回NMHEADER结构,其中包含有关正在拖动的标题项的信息。这是代码示例;你也可以关注帖子的commented version

uses
  ComCtrls, CommCtrl;

type
  TListView = class(ComCtrls.TListView)
  private
    procedure WMNotify(var AMessage: TWMNotify); message WM_NOTIFY;
  end;

implementation

{ TListView }

procedure TListView.WMNotify(var AMessage: TWMNotify);
var
  HeaderHandle: HWND;
begin
  inherited;
  if (AMessage.NMHdr^.code = HDN_ENDDRAG) then
  begin
    HeaderHandle := ListView_GetHeader(Handle);
    if (AMessage.NMHdr^.hWndFrom = HeaderHandle) then
    ShowMessage(
      'The header with index ' +
      IntToStr(TWMNotifyHC(AMessage).HDNotify^.Item) + ' ' +
      'has been dragged to the position with index ' +
      IntToStr(TWMNotifyHC(AMessage).HDNotify^.PItem^.iOrder) + '. ' +
      'Columns are not updated yet!');
  end;
end;

答案 1 :(得分:1)

您没有得到任何已移动列的指示。发生的情况是列表视图的Columns列表中的项目被重新排列,以匹配列表视图中列的新顺序。只要您可以唯一地标识每列,而不是使用列中列的位置,那么您可以推断列的顺序。

一种可能的方法是为每列提供不同的Tag值。然后你可以做这样的事情:

procedure TForm1.ListView1ColumnDragged(Sender: TObject);
var
  i: Integer;
  s: string;
begin
  s := '';
  for i := 0 to ListView1.Columns.Count-1 do begin
    s := s + IntToStr(ListView1.Columns[i].Tag) + ' ';
  end;
  Caption := Trim(s);
end;

当然,你会想要做一些比这更有用的事情,但我相信它可以解决这个问题。