博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Delphi在Listview中加入Edit控件
阅读量:5057 次
发布时间:2019-06-12

本文共 5456 字,大约阅读时间需要 18 分钟。

原帖 : 

 Listview是一个非常有用的控件,我们常常将大量的数据(如里的数据)导入到Listview中,有的时候我们需要编辑Listview里的数据,而它并不提供编辑的功能,怎么样才能使它具有编辑功能呢?你可以试试下面这种方法。

         首先在FORM1中放置一个Listview控件和一个Edit控件。Edit控件有什么用?当然是用来编辑Listview里的内容,程序的想法是这样的:当鼠标点击了Listview控件后,根据鼠标位置将Edit控件放置到Listview对应的Column里,将对应Item里的内容读入Edit中,在Edit中编辑好后,再将Edit编辑过的信息回写到Item中。

        代码如下:

   

unit Unit1;    interface    uses     Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,     Dialogs, ComCtrls, CommCtrl, StdCtrls, ImgList;    type    TForm1 = class(TForm)      ListView1: TListView;      Edit1: TEdit;      procedure Edit1KeyDown(Sender: TObject; var Key: Word;        Shift: TShiftState);      procedure Edit1Change(Sender: TObject);      procedure ListView1MouseDown(Sender: TObject; Button: TMouseButton;        Shift: TShiftState; X, Y: Integer);      procedure FormCreate(Sender: TObject);      procedure ListView1ColumnDagged(Sender: TObject);    private      {
Private declarations } FListViewWndProc1: TWndMethod; procedure ListViewWndProc1(var Msg: TMessage); public {
Public declarations } end; const MaxColumns=3 ; // 总Columns-1 var Form1: TForm1; edtcol:integer; //记录EDIT1在Columns中的位置,1- MaxColumns; editem:Tlistitem; implementation {
$R *.dfm} //拦截LISTVIEW1消息 procedure TForm1.ListViewWndProc1(var Msg: TMessage); var IsNeg : Boolean; begin try ShowScrollBar(ListView1.Handle, SB_HORZ, false); //拖动Listview1滚动条时,将EDIT1隐藏起来 if(msg.Msg =WM_VSCROLL) or (msg.Msg=WM_MOUSEWHEEL ) then edit1.Visible :=false; if Msg.Msg = WM_MOUSEWHEEL then begin if listview1.Selected=nil then exit; IsNeg := Short(msg.WParamHi) < 0; listview1.SetFocus ; if IsNeg then SendMessage(edit1.Handle, WM_KEYDOWN, VK_down, 0) else SendMessage(edit1.Handle, WM_KEYDOWN, VK_up, 0); end else FListViewWndProc1(Msg); except end; end; //拦截EDIT的按键消息,对上、下、左、右方向键进行处理------ procedure TForm1.Edit1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); var item:tlistitem; ix,lt,i:integer; rect:Trect; begin TRY //----对上、下、左、右方向键进行处理----------------- if(key<>VK_DOWN) AND (KEY<>VK_UP) AND (KEY<>VK_RIGHT) AND (KEY<>VK_LEFT) THEN EXIT; IF(KEY=VK_RIGHT) THEN //键盘右键 BEGIN //按下键盘右键后,判断光标位置是否处于最右边,如果不在最右边,不作处理 EXIT if length(edit1.Text)>edit1.SelStart then exit; item:=listview1.Selected; //计算edit1位于哪个Columns,如果
<最大columns,+1,否则=1,即转到最左边 if(edtcol 从 edtcol值计算出 columns的位置(left,width),edit1按此设置 lt:="lt+listview1.Columns[i].Width;" for i:="0" to edtcol-1 do edit1.left:="lt+1;" edit1.width :="listview1.Columns[edtcol].Width;" end; if(key="VK_left)" then 键盘左键 begin if edit1.selstart<>
0 then exit; item:=listview1.Selected; if(edtcol>0) then edtcol:=edtcol-1 else edtcol:=MaxColumns; lt:=0; for i:=0 to edtcol-1 do lt:=lt+listview1.Columns[i].Width; edit1.Left:=lt+1; edit1.Width :=listview1.Columns[edtcol].Width; END; if(key=VK_DOWN ) then //键盘下键 begin item:=listview1.Selected; if item=nil then exit; ix:=item.Index; if ix>=listview1.Items.Count-1 then exit; SendMessage(listview1.Handle, WM_KEYDOWN, VK_down, 0) end; if(key=VK_UP) then //键盘上键 begin item:=listview1.Selected; if item=nil then exit; ix:=item.Index; if ix<1 then exit; SendMessage(listview1.Handle, WM_KEYDOWN, VK_up, 0) end; listview1.ItemFocused :=listview1.Selected; item:=listview1.Selected ; edit1.Visible :=false; rect:=item.DisplayRect(drSelectBounds); edit1.SetBounds(edit1.left,rect.Top-1,edit1.Width,rect.Bottom-rect.Top+2); IF edtcol>0 then edit1.Text:=item.SubItems[edtcol-1] else edit1.Text:=item.Caption ; edit1.Visible:=true; edit1.SetFocus; EXCEPT END; end; //编辑控件内容改变后,保存改变到Listview1对应位置 procedure TForm1.Edit1Change(Sender: TObject); begin TRY if not edit1.Visible then exit; listview1.Selected.SubItems[edtcol-1]:=edit1.Text; EXCEPT END; end; //在LISTVIEW1上按下鼠标 procedure TForm1.ListView1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var rect:Trect; p:tpoint; wtmp,i:integer; begin TRY //显示编辑控件 edit1.Visible:=false; //根据鼠标位置,得到所对应行的LISTITEM editem:=listview1.GetItemAt(x,y); if editem<>nil then begin //根据鼠标位置,计算出是哪个 Columns. p:=editem.Position; wtmp:=p.X; for i:=0 to listview1.Columns.Count-1 do if (x>wtmp) and (x<(wtmp+listview1.Column[i].Width)) then break //找到对应的Columns,打断退出,I确定. else inc(wtmp,listview1.Column[i].Width); //根据I的值,取得 Columns的对应位置。在对应位置按其它的SIZE放EDIT1。 edtcol:=i; rect:=editem.DisplayRect(drSelectBounds); edit1.SetBounds(wtmp-1,rect.Top-1,listview1.Column[i].Width+1,rect.Bottom-rect.Top+2); if edtcol>0 then edit1.Text:=editem.SubItems[i-1] else edit1.Text:=editem.Caption; edit1.Visible:=true; edit1.SetFocus; end; EXCEPT END; end; //初始化,加入测试数据. procedure TForm1.FormCreate(Sender: TObject); var item:tlistitem; i:integer; begin //将edit1的父亲选为LISTVIEW1,用以响应LISTVIEW1消息 edit1.parent:=Listview1; //拦载LISTVIEW1鼠标消息 FListViewWndProc1:=ListView1.WindowProc; ListView1.WindowProc := ListViewWndProc1; for i:=0 to 10 do begin item:=listview1.Items.Add ; item.Caption :='123324'; item.SubItems.Add('32r5aefs'); item.SubItems.Add('SGASD'); item.SubItems.Add('3445645'); end; end;

 

 

  上面的代码只是最基本的代码,仅可以通过键盘的上、下、左、右键控制EDIT在各个Column中切换,要将它做得更好,还要加入如拦截Column的宽度变化消息,以便Column变宽或变窄后相应的调整EDIT宽度等等。

 

转载于:https://www.cnblogs.com/yzryc/p/6401752.html

你可能感兴趣的文章
硬件笔记之Thinkpad T470P更换2K屏幕
查看>>
一个关于vue+mysql+express的全栈项目(六)------ 聊天模型的设计
查看>>
【知识库】-数据库_MySQL 的七种 join
查看>>
.net 写文件上传下载webservice
查看>>
noSQL数据库相关软件介绍(大数据存储时候,必须使用)
查看>>
iOS开发——缩放图片
查看>>
HTTP之URL的快捷方式
查看>>
满世界都是图论
查看>>
配置链路聚合中极小错误——失之毫厘谬以千里
查看>>
代码整洁
查看>>
蓝桥杯-分小组-java
查看>>
Java基础--面向对象编程1(类与对象)
查看>>
Android Toast
查看>>
iOS开发UI篇—Quartz2D使用(绘制基本图形)
查看>>
docker固定IP地址重启不变
查看>>
桌面图标修复||桌面图标不正常
查看>>
JavaScript基础(四)关于对象及JSON
查看>>
关于js sort排序方法
查看>>
JAVA面试常见问题之Redis篇
查看>>
javascript:二叉搜索树 实现
查看>>