zoukankan      html  css  js  c++  java
  • 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;

    调试可以看到,在点击网格进入编辑状态后,就会显示下列按钮

  • 相关阅读:
    堆栈的分布
    Socket网络编程(TCP/IP/端口/类)和实例
    c语言字节对齐
    理一理字节对齐的那些事
    Socket网络编程(TCP/IP/端口/类)和实例
    socket、端口、进程的关系
    SMT32 启动文件详细解说
    Chapter 1 First Sight——22
    Leetcode389
    Chapter 1 First Sight——21
  • 原文地址:https://www.cnblogs.com/guorongtao/p/4869184.html
Copyright © 2011-2022 走看看