原帖 : http://www.cnblogs.com/hssbsw/archive/2012/06/03/2533092.html

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= ; // 总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) < ;
listview1.SetFocus ;
if IsNeg then
SendMessage(edit1.Handle, WM_KEYDOWN, VK_down, )
else
SendMessage(edit1.Handle, WM_KEYDOWN, VK_up, );
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:=;
for i:= to edtcol- do lt:=lt+listview1.Columns[i].Width;
edit1.Left:=lt+;
edit1.Width :=listview1.Columns[edtcol].Width;
END;
IF(KEY=VK_left) THEN //键盘左键
BEGIN
if edit1.SelStart<> then exit;
item:=listview1.Selected;
if(edtcol>) then edtcol:=edtcol- else edtcol:=MaxColumns;
lt:=;
for i:= to edtcol- do lt:=lt+listview1.Columns[i].Width;
edit1.Left:=lt+;
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- then exit;
SendMessage(listview1.Handle, WM_KEYDOWN, VK_down, )
end;
if(key=VK_UP) then //键盘上键
begin
item:=listview1.Selected;
if item=nil then exit;
ix:=item.Index;
if ix< then exit;
SendMessage(listview1.Handle, WM_KEYDOWN, VK_up, )
end;
listview1.ItemFocused :=listview1.Selected;
item:=listview1.Selected ;
edit1.Visible :=false;
rect:=item.DisplayRect(drSelectBounds);
edit1.SetBounds(edit1.left,rect.Top-,edit1.Width,rect.Bottom-rect.Top+);
IF edtcol> then edit1.Text:=item.SubItems[edtcol-]
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-]:=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:= to listview1.Columns.Count- 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-,rect.Top-,listview1.Column[i].Width+,rect.Bottom-rect.Top+);
if edtcol> then edit1.Text:=editem.SubItems[i-]
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:= to do
begin
item:=listview1.Items.Add ;
item.Caption :='';
item.SubItems.Add('32r5aefs');
item.SubItems.Add('SGASD');
item.SubItems.Add('');
end;
end;

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

Delphi在Listview中加入Edit控件的更多相关文章

  1. delphi Components[i]清除所有edit控件中的内容

    (* 一般的清空combobox方法 combobox1.clear; ... combobox9.clear; *)   procedure TForm1.Button1Click(Sender: ...

  2. Android关于ListView中item与控件抢夺焦点的那些事

    在开发中,listview可以说是我们使用最频繁的控件之一了,但是关于listview的各种问题也是很多.当我们使用自定义布局的Listview的时候,如果在item的布局文件里面存在Button或者 ...

  3. listView中的button控件获取item的索引

    在listview中的listitem设置事件响应,如果listitem中有button控件,这时候listitem就不会捕获到点击事件,而默认的是listitem中的button会捕获点击事件.那么 ...

  4. Delphi 在DLL中使用DevExpress控件时出错解决办法

    测试环境 DevExpress VCL 14.1.3 和XE7 问题:在dll使用cxGrid控件时  如果不添加列标题 则不报错   查询无数据集显示,如果加上标题 就报错了 这段为报错部分 fun ...

  5. listView中的button控件获取索引

    1.在listitem中初始化button的时候,给该button添加一个setTag方法,将此时的索引值传进去,然后在button的onclick事件中调用view的getTag方法,即可将list ...

  6. Windows获取其他进程中Edit控件的内容

    最近做的MFC项目中,有个获取其他进程中Edit控件内容的需求,本来以为是个很简单的问题,但是来来回回折腾了不少时间,发博记录一下. 刚开始拿到这个问题,很自然的就想到GetDlgItemText() ...

  7. Delphi中使用TXMLDocument控件应注意的问题 转

    Delphi中使用TXMLDocument控件应注意的问题 delphiconstructorxmlclass今天写了一个类,其中用到了TXMLDocument控件.这个控件我是要动态生成的. 但是却 ...

  8. vc 在edit控件中动态插入数据滚动显示

    内存从网上论坛摘抄整理 思路:给控件设置多行属性,设置垂直滚动条,Auto Vscroll设置为true,放入文本后把插入点设置到末尾 pEdit->LineScroll(pEdit->G ...

  9. 修改Delphi 10.1.2 edit控件在android的复制、剪切和粘贴样式

    Delphi 10.1.2 edit控件在android默认的复制.剪切和粘贴样式太丑,经悟能-DelphiTeacher的提示,用最简单的代码修改后稍有改观. 默认的样式: 修改后的样式: 修改FM ...

随机推荐

  1. Find the peace with yourself

    The purpose of being mature is to find the real calm and peace with yourself. Or you can say the tur ...

  2. $.extend与$.fn.extend()

    很多情况下,用户需要对jQuery插件进行二次开发,那么我们来看看JQ原开发者为我们提供的两种扩展插件的方式如下: 1.类别类:相当于为jquery扩展一个类,比如现在我要扩展一个简单的想加的功能函数 ...

  3. samba安装

    第一步下载: wget https://download.samba.org/pub/samba/stable/samba-4.6.7.tar.gz 看了下没看到啥有用的直接安装: ./configu ...

  4. tips:Java基本数据类型大小比较

    tips:Java基本数据类型大小比较! Java语言提供了八种基本类型.六种数字类型(四个整数型,两个浮点型),一种字符类型,还有一种布尔型. ------四个整数型------ (1)byte:b ...

  5. MariaDB MaxScale

    1. down https://mariadb.com/downloads/#mariadb_platform-mariadb_maxscale (1) install sudo yum locali ...

  6. iPhone 获取指定格式的时间和日期

    1.  显示当前的年月日+时间 NSDate* date = [NSDate date]; NSDateFormatter* formatter = [[[NSDateFormatter alloc] ...

  7. uva-10132-排序

    题意: 有很多文件,碎成了俩片,问,原来的文件是什么,如果有多个答案,任意一个答案就行,输入2N个字符串,拼接成N个文件. 直接排序,正确的答案一定是某个长度最短的和某个最长的连在一起. #inclu ...

  8. mysql 替代Oracle instr

    在迁移项目时遇到的,原项目的数据库使用的Oracle,现在要迁移到MySQL中,而项目中用到了Oracle的instr函数,而MySQL只能查找子串是否在父串中,没法按照出现的次数进行查找. 先来介绍 ...

  9. <转载> bat 脚本基本语法 http://blog.csdn.net/bluedusk/article/details/1500629

        bat 脚本基本语法 2007-01-25 10:31 常用命令 echo.@.call.pause.rem(小技巧:用::代替rem)是批处理文件最常用的几个命令,我们就从他们开始学起. = ...

  10. 32. 安装oracle11g时,先决条件一直失败的解决方法

    解决方法:1. 在命令提示符下 net share c$=c: 补充: 如果这个命令提示错误:“发生系统错误 5,拒绝访问的时候”,那我们可以修改注册表,检查AutoShareServer和AutoS ...