TStringGrid 实现下拉框
TStringGrid 实现下拉框比较常见的思路是在TSringGrid中嵌入一个TComboBox ,
思路虽然简单,但开发起来却很麻烦,而且有时会出现不愿看到的效果。
还有一种更巧的方法,是Delphi未公开的。
先看两个Delphi提供的VCL:
TInplaceEdit 是Delphi 提供的一个未公开的控件,只能内嵌于TCustomGrid
中使用,TStringGrid 单元格的编辑功能就是由该控件实现的。
TInplaceEditList 是TInplaceEdit的子控件,该控件实现了下拉框和带省略号
的按钮的功能,也是只能在TCustomGrid 中使用。
OnEditButtonClick 事件,按钮按下时触发该事件。
OnGetPickListitems 事件,下拉框弹出前触发该事件,在该事件的处
理中可以改变下拉框的内容。
TEditStyle =(esSimple, esEllipsis, esPickList)。
编辑器类型,esSimple 普通类型,esEllipsis 带省略号按钮类型,
esPickList 下拉框类型。
TCustomGrid ,看一下它的两个protected函数:
FInplaceEdit: TInplaceEdit;
FInplaceEdit 是TCustomGrid的编辑器。
Function GetEditStyle(ACol, ARow: Longint): TEditStyle; dynamic;
获取给定单元格的编辑器属性。
Function CreateEditor: TInplaceEdit; virtual;
TCustomGrid 创建编辑器。
TCustomGrid 只对这两个函数作了最基本的实现,其源代码如下:
function TCustomGrid.CreateEditor: TInplaceEdit;
begin
Result := TInplaceEdit.Create(Self);
end;
function TCustomGrid.GetEditStyle(ACol, ARow: Longint): TEditStyle;
begin
Result := esSimple;
end;
TStringGrid 没有改变这两个函数,因此TStringGrid没法用TInplaceEditList
实现下拉框功能 。
实现原理:
TStringGird 第一次进入编辑状态前由CreateEditor 创建编辑器,在编辑器
显示前会访问TCustomGrid.GetEditStyle 函数,并由该函数的返回值决定编
辑器类型。对于TInplaceEditList而言,如果GetEditStype 返回esEllipsis ,
就是具有按钮功能的编辑器,如果返回值是esPickList ,就是下拉框类型的编
辑器,并在显示之前触发OnGetPickListitems事件。因此在TStringGrid的子控
件中重新实现这两个函数,首先使CreateEditor创建的编辑器为TinplaceEditList
型的,然后在GetEditSyle函数中引出OnGetEditStyle事件,在应用环境中决定编
辑的类型。
unit DropListGrid;
interface
uses
Windows, Messages, SysUtils, Classes, Controls, Grids,Forms;
type
TOnGetEditStyle = procedure(ACol, ARow: Integer;var EditStyle:TEditStyle) of Object;
TOnGridEditButtonClick=procedure(Sender:TObject;ACol,ARow:Integer)of Object;
TDropListGrid = class(TStringGrid)
private
{ Private declarations }
FButtonWidth: Integer;
FDropDownRows: Integer;
FOnEditButtonClick: TOnGridEditButtonClick;
FOnGetPickListitems: TOnGetPickListItems;
FOnGetEditStyle: TOnGetEditStyle;
procedure setFButtonWidth(const Value: Integer);
procedure setFDropDownRows(const Value: Integer);
procedure SetFOnEditButtonClick(const Value: TOnGridEditButtonClick);
procedure SetFOnGetPickListitems(const Value: TOnGetPickListItems);
procedure SetOnGetEditStyle(const Value: TOnGetEditStyle);
procedure ButtonClick(Sender: TObject);
procedure GetPickListitems(ACol, ARow: Integer; Items: TStrings) ;
protected //TInplaceEditList
{ Protected declarations }
function CreateEditor: TInplaceEdit;override;
function GetEditStyle(ACol, ARow: Longint): TEditStyle; override;
public
{ Public declarations }
destructor Destroy; override;
published
{ Published declarations }
property ButtonWidth: Integer read FButtonWidth write setFButtonWidth;
property DropDownRows: Integer read FDropDownRows write setFDropDownRows;
property OnEditButtonClick: TOnGridEditButtonClick read FOnEditButtonClick
write SetFOnEditButtonClick;
property OnGetPickListitems: TOnGetPickListItems read FOnGetPickListitems
write SetFOnGetPickListitems;
property OnGetEditStyle:TOnGetEditStyle read FOnGetEditStyle write SetOnGetEditStyle;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('SelfVcl', [TDropListGrid]);
end;
{ TDropListGrid }
procedure TDropListGrid.ButtonClick(Sender: TObject);
begin
if Assigned(FOnEditButtonClick) then
FOnEditButtonClick(Self,Col,Row);
end;
function TDropListGrid.CreateEditor: TInplaceEdit;
begin
Result := TInplaceEditList.Create(Self);
result.Parent:=Self;
with TInplaceEditList(result)do
begin
Font:=Self.Font;
if FButtonWidth>0 then
ButtonWidth:= FButtonWidth;
if FDropDownRows>0 then
DropDownRows:=FDropDownRows;
OnEditButtonClick:=ButtonClick;
OnGetPickListitems:=GetPickListitems;
end;
end;
destructor TDropListGrid.Destroy;
begin
if InplaceEditor<>nil then
if TInplaceEditList(InplaceEditor).PickListLoaded then
TInplaceEditList(InplaceEditor).PickList.Items.Clear;
inherited;
end;
function TDropListGrid.GetEditStyle(ACol, ARow: Integer): TEditStyle;
begin
result:=inherited GetEditStyle(ACol, ARow);
if Assigned(FOnGetEditStyle) then
FOnGetEditStyle(ACol,ARow,result);
end;
procedure TDropListGrid.GetPickListitems(ACol, ARow: Integer;
Items: TStrings);
begin
if Assigned(FOnGetPickListitems) then
FOnGetPickListitems(ACol,ARow,Items);
end;
procedure TDropListGrid.setFButtonWidth(const Value: Integer);
begin
FButtonWidth := Value;
if InplaceEditor<>nil then
TInplaceEditList(InplaceEditor).ButtonWidth:=Value;
end;
procedure TDropListGrid.setFDropDownRows(const Value: Integer);
begin
FDropDownRows := Value;
if InplaceEditor<>nil then
TInplaceEditList(InplaceEditor).DropDownRows:=Value;
end;
procedure TDropListGrid.SetFOnEditButtonClick(const Value: TOnGridEditButtonClick);
begin
FOnEditButtonClick := Value;
end;
procedure TDropListGrid.SetFOnGetPickListitems(
const Value: TOnGetPickListItems);
begin
FOnGetPickListitems := Value;
end;
procedure TDropListGrid.SetOnGetEditStyle(const Value: TOnGetEditStyle);
begin
FOnGetEditStyle := Value;
end;
end.
==============下面是我生成SelVcl的过程
1、在delphi中新建一个component
2、将以上代码张贴到新建单元中
3、编译生成一个Pas文件在Lib目录下
4、通过install component加入到SelVcl
5、新建一个工程,在SelVcl页中使用该控件
6、设置属性:goEditing:=true;
7、在OnGetEditStyle事件中写EditStyle:= esPickList;
调试可以看到,在点击网格进入编辑状态后,就会显示下列按钮
TStringGrid 实现下拉框的更多相关文章
- jquery实现下拉框多选
一.说明 本文是利用EasyUI实现下拉框多选功能,在ComboxTree其原有的基础上对样式进行了改进,样式表已上传demo,代码如下 二.代码 <!DOCTYPE html PUBLIC & ...
- 利用js取到下拉框中选择的值
现在的需求是:下拉框中要是选择加盟商让其继续选择学校,要是选择平台管理员则不需要选择学校.隐藏选择下拉列表. 选择枚举值: /// <summary> /// 平台角色 /// </ ...
- jquery禁用下拉框
禁用下拉框 //下拉框禁用 $("select").each(function () { $("#" + this.id).attr("disable ...
- [原创]自己动手实现React-Native下拉框控件
因项目需要,自己动手实现了一个下拉框组件,最近得空将控件独立出来开源上传到了Github和npm. Github地址(求Star 求Star 求Star
- ajax 多级联动 下拉框 Demo
写了ajax实现级联下拉框,考虑常用,并且级联个数随不同业务个数不同,于是就整理了一下,实现了 ajax + N级联动 下拉框的效果 效果图 HTML 代码 <h2> 省级联动</h ...
- jquery Combo Select 下拉框可选可输入插件
Combo Select 是一款友好的 jQuery 下拉框插件,在 PC 浏览器上它能模拟一个简单漂亮的下拉框,在 iPad 等移动设备上又能回退到原生样式.Combo Select 能够对选项进行 ...
- struts-hibernate-ajax完成区县和街道级联下拉框功能(二补充使用json解析list结果集,ajax循环json层级处理)
针对<struts-hibernate-ajax完成区县和街道级联下拉框功能>进行补充,上一篇中,要在action中拼接JSON格式字符串,很容易手抖.直接用json处理一下转成json格 ...
- asp.net MVC4 表单 - 下拉框
1.下拉框代码方式 控制器内构建下拉项目: List<SelectListItem> list = new List<SelectListItem>(); list.Add(n ...
- Jquery制作--美化下拉框
平常我们用的原生select下拉框,大部分样式没办法修改,导致在不同的浏览器里面会跟设计图的风格大相径庭.所以为了能让它美化起来,就用JQ模拟了一个下拉框,可以随意定义样式.原生的下拉框也保留在div ...
随机推荐
- 转载 如何理解API,API 是如何工作的
本文转载于https://blog.csdn.net/cumtdeyurenjie/article/details/80211896 感谢作者 仁杰兄 大家可能最近经常听到 API 这个概念,那什么是 ...
- spring boot 四大组件之Starter
1.概述 依赖管理是任何复杂项目的关键方面.手动完成这些操作并不理想; 你花在它上面的时间越多,你在项目的其他重要方面所花费的时间就越少. 构建Spring Boot启动器是为了解决这个问题.Star ...
- leetcood学习笔记-27-移除元素
题目: 第一次提交: class Solution: def removeElement(self, nums, val: int) -> int: for i in range(len(num ...
- SQL 循环语句几种写法
1.正常循环语句 declare @orderNum varchar(255)create table #ttableName(id int identity(1,1),Orders varchar( ...
- Alibaba Cloud Toolkit,你确定不来尝鲜一下?
阿里云出了新的工具,Alibaba Cloud Toolkit,看看“toolkit”这个名字就知道它是一个工具集. 没错!它就是一个工具集,一个集打包部署发布以及探索分析程序的工具集.而我,目前还停 ...
- 原生js 与 jQuery对比
1.原生JS与jQuery操作DOM对比 : https://www.cnblogs.com/QianBoy/p/7868379.html 2.比较jQuery与JavaScript的不同功能实 ...
- git回退单个文件
git原理 Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD. gi ...
- win 解除鼠标右键关联
点击「开始」→「运行」→「输入Regedit」→「确定」,打开注册表编辑器,找到子键: 「HKEY_CLASSES_ROOT\*\shellex\UltroEdit」,删除此项即可:
- Xen的半虚拟化(Paravirtualization)
三个特权级 IA-32体系提供了4个特权级别,正常情况下只用了2个, 操作系统运行在Ring 0,而应用程序运行在Ring 3. Xen让自己运行在Ring 0, 而操作系统运行在Ring 1, 应用 ...
- 如何发现 Redis 热点 Key ,解决方案有哪些?
Java技术栈 www.javastack.cn 优秀的Java技术公众号 来源:http://t.cn/EAEu4to 一.热点问题产生原因 热点问题产生的原因大致有以下两种: 1.1 用户消费的数 ...