我有一个包含3列的ListView,想要编辑第三列,也就是Subitem [1].如果我将ListView.ReadOnly设置为True,它允许我编辑所选项目的标题.是否有一种简单的方法为子项目做同样的事情?我想远离在编辑上面添加无边框控件.
解决方法@H_502_4@
您可以使用TEdit,自定义消息编辑listview的子项(在报告模式下)并处理ListView的OnClick事件.
试试这个样本
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',2]));
Item.SubItems.Add(Format('%d.%d',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,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;
试试这个样本
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',2])); Item.SubItems.Add(Format('%d.%d',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,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;