Delphi在Listview中加入Edit控件
原帖 : 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控件的更多相关文章
- delphi Components[i]清除所有edit控件中的内容
(* 一般的清空combobox方法 combobox1.clear; ... combobox9.clear; *) procedure TForm1.Button1Click(Sender: ...
- Android关于ListView中item与控件抢夺焦点的那些事
在开发中,listview可以说是我们使用最频繁的控件之一了,但是关于listview的各种问题也是很多.当我们使用自定义布局的Listview的时候,如果在item的布局文件里面存在Button或者 ...
- listView中的button控件获取item的索引
在listview中的listitem设置事件响应,如果listitem中有button控件,这时候listitem就不会捕获到点击事件,而默认的是listitem中的button会捕获点击事件.那么 ...
- Delphi 在DLL中使用DevExpress控件时出错解决办法
测试环境 DevExpress VCL 14.1.3 和XE7 问题:在dll使用cxGrid控件时 如果不添加列标题 则不报错 查询无数据集显示,如果加上标题 就报错了 这段为报错部分 fun ...
- listView中的button控件获取索引
1.在listitem中初始化button的时候,给该button添加一个setTag方法,将此时的索引值传进去,然后在button的onclick事件中调用view的getTag方法,即可将list ...
- Windows获取其他进程中Edit控件的内容
最近做的MFC项目中,有个获取其他进程中Edit控件内容的需求,本来以为是个很简单的问题,但是来来回回折腾了不少时间,发博记录一下. 刚开始拿到这个问题,很自然的就想到GetDlgItemText() ...
- Delphi中使用TXMLDocument控件应注意的问题 转
Delphi中使用TXMLDocument控件应注意的问题 delphiconstructorxmlclass今天写了一个类,其中用到了TXMLDocument控件.这个控件我是要动态生成的. 但是却 ...
- vc 在edit控件中动态插入数据滚动显示
内存从网上论坛摘抄整理 思路:给控件设置多行属性,设置垂直滚动条,Auto Vscroll设置为true,放入文本后把插入点设置到末尾 pEdit->LineScroll(pEdit->G ...
- 修改Delphi 10.1.2 edit控件在android的复制、剪切和粘贴样式
Delphi 10.1.2 edit控件在android默认的复制.剪切和粘贴样式太丑,经悟能-DelphiTeacher的提示,用最简单的代码修改后稍有改观. 默认的样式: 修改后的样式: 修改FM ...
随机推荐
- Ribbon Workbench 与此流程相关的流程操作未激活
问题描述:使用Ribbon Workbench 打开解决方案时报 :与此流程相关的流程操作未激活 解决方法 :ribbon 导航--系统定置--流程中心--流程--CustomiseRibbon -- ...
- 第11章 拾遗3:虚拟局域网(VLAN)
1. 虚拟局域网(VLAN) (1)VLAN是建立在物理网络基础上的一种逻辑子网,它将把一个LAN划分成多个逻辑的局域网(VLAN),每个VLAN是一个广播域,VLAN内的主机间通信就和在一个LAN内 ...
- Visual Studio 20年
这是一个暴露年龄的话题,如果一个程序员从第一个版本开始使用Visual Studio的话,现在应该是40多岁的中年大叔了.我的程序员生涯是从Visual basic 6.0 (vb6)开始的,一晃就过 ...
- Java——word分词·自定义词库
word: https://github.com/ysc/word word-1.3.1.jar 需要JDK8word-1.2.jar c语言给解析成了“语言”,自定义词库必须为UTF-8 程序一旦运 ...
- CS229 4.Logistic Regression
- studio2.3app签名打包安装失败,找不到签名证书。
Androidstudio升级到2.3后,打包时和之前不一样了. 如果只选择V2,是未签名的.所以要把V1和V2都打勾.
- 「ZJOI2015」地震后的幻想乡
/* 难度最低的解法 钦定一个边集S作为前S小如果这个边集假如第|S|小这条边时加入时S恰好联通, 那么我们就能够算出他的贡献了 恰好联通 = 加了这条边之前不连通方案数 - 加了这条边之后不连通方案 ...
- django+uwsgi+nginx+sqlite3部署+screen
note:可通过该命令查找文件未知 sudo find / -name filename 一:项目(github) ssh root@server ip # 连接你的服务器 git ...
- python生成器异步使用
import dis,time # 反汇编 import threading def request(): print('start request') v = yield print(v) def ...
- 关于xampp默认安装后mysql/mariadb密码的修改
关于xampp默认按照后mysql/mariadb密码的修改 默认安装的mysql/mariadb 是没有密码的 只能跳过 然后进行修改密码 /opt/lampp/bin/mysqld_safe - ...