DELPHI XE10, 使用TCOLLECTION类在设计期给stringgrid添加一列表头

delphi 自带的stringgrid在设计期,给第一行各列添加一个表头。

经过实验, 从Tstringgrid派生一个类,TMystrgrid, 增加一个collection属性,FLISTPROPS,

tlistprops从TCOLLECTION继承,添加一个FOWNER字段,如下

type
    TListProps = class; // 这个类是用于表示该List属性的集合类型

    TMyStrGrid = class(TStringGrid)
    private
        FRowHeaders: TStringList;
        FListProps: TListProps;
        
        procedure SetListProps(const Value: TListProps);
       
        { Private declarations }
    protected
        { Protected declarations }
        
    public
        { Public declarations }
        constructor Create(AOwner: Tcomponent); override;
        destructor Destroy; override;

    published
        { Published declarations }
        property ListProps: TListProps read FListProps write SetListProps;
        // List属性集合表示每列的表头字段
        
    end;

    TListItem = class(TCollectionItem)
    private
       
        FCaption: string;
        procedure SetCaption(const Value: string);
    protected
       
    public
        constructor Create(Collection: TCollection); override;
        destructor Destroy; override;
        procedure Assign(source: TPersistent); override;
        // 因为需要进行赋值操作,必须重载该方法,将数据域进行copy
    published
        property Caption: string read FCaption write SetCaption;
    end;

    TListProps = class(TCollection)
    private
        // fowner这个属性是必须的,因为对于List属性,
        // 如果在设计时在弹出的窗口中进行了编辑,必须将修改的结果反应到原始控件中,
        // 这里通过这个属性表明了List属性的所有者(Owner),
        // 这样在List属性被修改时可以通知Owner作出相应调整,
        // 与之相应的,一般在这个类里还需要重载:
        // procedure Update(Item: TCollectionItem); override;这个方法
        FOwner: TMyStrGrid;
        function GetItem(Index: Integer): TListItem;
        procedure SetItem(Index: Integer; const Value: TListItem);
    protected
        function GetOwner: TPersistent; override;
        procedure Update(Item: TCollectionItem); override;
    public
        constructor Create(AOwner: TMyStrGrid);
        function Add: TListItem;
//         procedure Delete(Index: Integer);
        property Items[Index: Integer]: TListItem read GetItem
            write SetItem; default;
    published

    end;

经过多次尝试,终于知道在集合项的值CAPTION改变时setcaption方法中需要通知集合类listprops更新update.

procedure Register;

implementation

procedure Register;
begin
    RegisterComponents('Samples', [TMyStrGrid]);
end;

{ TMyStrGrid }

constructor TMyStrGrid.Create(AOwner: Tcomponent);
begin
    inherited;
    self.FListProps := TListProps.Create(self);

end;

destructor TMyStrGrid.Destroy;
begin
    FreeAndNil(FListProps);
    inherited;
end;

procedure TMyStrGrid.SetListProps(const Value: TListProps);
begin
    ListProps.Assign(Value);
end;


{ TListItem }

procedure TListItem.Assign(source: TPersistent);
begin
    inherited;
    if source is TListItem then
    begin
        if assigned(Collection) then
            Collection.BeginUpdate;
        FCaption := TListItem(source).FCaption;
        Collection.EndUpdate;
    end
    else
        inherited Assign(source);
end;

constructor TListItem.Create(Collection: TCollection);
begin
    inherited Create(Collection);
    FCaption := '';
end;

destructor TListItem.Destroy;
begin

    inherited Destroy;
end;

procedure TListItem.SetCaption(const Value: string);
begin
    Collection.BeginUpdate;
    FCaption := Value;
    Collection.EndUpdate;
//此处使用beginupdate,endupdate才会自动调用collection的update函数,
//在update重载函数中更新对应的stringgrid的cells内容
end;

{ TListProps }

function TListProps.Add: TListItem;
begin
    result := TListItem(inherited Add);
//此处调用collection.beginupdate, endupdate不起作用。
end;

constructor TListProps.Create(AOwner: TMyStrGrid);
begin
    inherited Create(TListItem);
    FOwner := AOwner;

end;

function TListProps.GetItem(Index: Integer): TListItem;
begin
    result := TListItem(inherited Items[Index]);
end;

function TListProps.GetOwner: TPersistent;
begin
    result := FOwner;
end;

procedure TListProps.SetItem(Index: Integer; const Value: TListItem);
begin
    inherited SetItem(index, Value);
end;

procedure TListProps.Update(Item: TCollectionItem);
var
    i: Integer;
begin
    if assigned(FOwner) then
    begin
        for i := 0 to Count - 1 do
            if i < FOwner.colcount then
            begin
                FOwner.Cells[i, 0] := Items[i].FCaption;
            end;
    end;
//这个过程中还需要考虑如果是删除了集合的item时,如何清除掉cells中多余的值
end;

end.

对于使用TSTRINGLIST表示表格的表头会比较简单,使用另外的思路。

欢迎交流。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值