我有一个包含3列的ListView,想要编辑第三列,也就是Subitem [1].如果我将ListView.ReadOnly设置为True,它允许我编辑所选项目的标题.是否有一种简单的方法为子项目做同样的事情?我想远离在编辑上面添加无边框控件.
解决方法
您可以使用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;