delphi - 在 TListView 中就地编辑子项

标签 delphi listview edit edit-in-place subitem

我有一个包含 3 列的 ListView,想要编辑第三列,即 Subitem[1]。如果我将 ListView.ReadOnly 设置为 False,它允许我编辑所选项目的标题。有没有一种简单的方法可以为子项目做同样的事情?我不想在顶部添加一个进行编辑的无边框控件。

最佳答案

您可以使用 TEdit、自定义消息并处理 ListView 的 OnClick 事件来编辑 ListView 的子项(在报告模式下)。

尝试这个示例

Const
  USER_EDITLISTVIEW = WM_USER + 666;

type
  TForm1 = class(TForm)
    ListView1: TListView;
    procedure FormCreate(Sender: TObject);
    procedure ListView1Click(Sender: TObject);
  private
    ListViewEditor: TEdit;
    LItem: TListitem;
    procedure UserEditListView( Var Message: TMessage ); message USER_EDITLISTVIEW;
    procedure ListViewEditorExit(Sender: TObject);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses
  CommCtrl;
const
  EDIT_COLUMN = 2; //Index of the column to Edit

procedure TForm1.FormCreate(Sender: TObject);
Var
  I : Integer;
  Item : TListItem;
begin
  for I := 0 to 9 do
  begin
   Item:=ListView1.Items.Add;
   Item.Caption:=Format('%d.%d',[i,1]);
   Item.SubItems.Add(Format('%d.%d',[i,2]));
   Item.SubItems.Add(Format('%d.%d',[i,3]));
  end;

  //create the TEdit and assign the OnExit event
  ListViewEditor:=TEdit.Create(Self);
  ListViewEditor.Parent:=ListView1;
  ListViewEditor.OnExit:=ListViewEditorExit;
  ListViewEditor.Visible:=False;
end;

procedure TForm1.ListView1Click(Sender: TObject);
var
  LPoint: TPoint;
  LVHitTestInfo: TLVHitTestInfo;
begin
  LPoint:= listview1.ScreenToClient(Mouse.CursorPos);
  ZeroMemory( @LVHitTestInfo, SizeOf(LVHitTestInfo));
  LVHitTestInfo.pt := LPoint;
  //Check if the click was made in the column to edit
  If (ListView1.perform( LVM_SUBITEMHITTEST, 0, LPARAM(@LVHitTestInfo))<>-1) and ( LVHitTestInfo.iSubItem = EDIT_COLUMN ) Then
    PostMessage( self.Handle, USER_EDITLISTVIEW, LVHitTestInfo.iItem, 0 )
  else
    ListViewEditor.Visible:=False; //hide the TEdit 
end;

procedure TForm1.ListViewEditorExit(Sender: TObject);
begin
  If Assigned(LItem) Then
  Begin
    //assign the vslue of the TEdit to the Subitem
    LItem.SubItems[ EDIT_COLUMN-1 ] := ListViewEditor.Text;
    LItem := nil;
  End;
end;

procedure TForm1.UserEditListView(var Message: TMessage);
var
  LRect: TRect;
begin
  LRect.Top := EDIT_COLUMN;
  LRect.Left:= LVIR_BOUNDS;
  listview1.Perform( LVM_GETSUBITEMRECT, Message.wparam,  LPARAM(@LRect) );
  MapWindowPoints( listview1.Handle, ListViewEditor.Parent.Handle, LRect, 2 );
  //get the current Item to edit
  LItem := listview1.Items[ Message.wparam ];
  //set the text of the Edit 
  ListViewEditor.Text := LItem.Subitems[ EDIT_COLUMN-1];
  //set the bounds of the TEdit
  ListViewEditor.BoundsRect := LRect; 
  //Show the TEdit
  ListViewEditor.Visible:=True;
end;

关于delphi - 在 TListView 中就地编辑子项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10835355/

相关文章:

xml - 使用能够在生成XML文件时写入流的解决方案来替换TXMLDocument(基于DOM)的XML生成

java - 为什么我在创建 ListView 时出错?

eclipse - 打开eclipse时出错-MAC

javascript - 如何自动滚动到 ListView 项目

hyperlink - 如何添加指向 django-autocomplete-light 所选项目的链接?

c++ - 使用 C++ 在 QDateEdit 中设置日期

delphi - VirtualStringTree - 外部控件不传递 TDragObject

Delphi服务无法启动

multithreading - 如何在 Delphi 中实现线程安全列表包装器?

C# listview 添加项目