求教怎样捕捉StringGrid中改变ColCount的事件。(100分)

  • 主题发起人 主题发起人 dadabox1
  • 开始时间 开始时间
D

dadabox1

Unregistered / Unconfirmed
GUEST, unregistred user!
我想写一个继承TStringGrid的控件,将TStringGrid中加一个动态数组。但在StringGrid
的Create事件中,只能得到ColCount=5,而我以后修改的ColCount应该在哪儿捕捉到呢?
我想一修改ColCount或RowCount,就能捕捉到,好即时加长我的动态数组,应该怎么做?
特急!!
 
TStringGrid好像没有事件直接由ColCount改变触发。
建议:
1。做一个自己的控件,由TStringGrid继承,修改SetColCount过程,添加自己的事件触发

2。或者尝试在OnTopLeftChanged加入代码,判断是否ColCount已经被修改
 
我也知道要这么做,但是我不会写,我不知道应该怎么做。请问怎样改写SetColCount过程?
哪位能否帮我改一下?
 
原SetColCount在private段,而且调用了其他定义在private中的方法,不太好改

换个思路,增加一个MyColCount属性,在其赋值时触发事件如何
以下为参考代码,你可以再改进一下

type
TForm1 = class(TForm)
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }

//demo event handle
procedure ColChanged(Sender : TObject);

end;

TMyStrGrid = class(TStringGrid)
private
FOnColCountChanged: TNotifyEvent;
procedure MyColCountChanged(Sender : TObject);
procedure SetMyColCount(Value: Longint);
procedure SetOnColCountChanged(const Value: TNotifyEvent);
function GetMyColCount: Longint;
public
published
property MyColCount: Longint read GetMyColCount write SetMyColCount;
property OnColCountChanged : TNotifyEvent read FOnColCountChanged write SetOnColCountChanged;
end;

var
Form1: TForm1;
MyStrGrid : TMyStrGrid;

implementation

{$R *.DFM}

{ TMyStrGrid }


function TMyStrGrid.GetMyColCount: Longint;
begin
Result := ColCount;
end;

procedure TMyStrGrid.MyColCountChanged(Sender: TObject);
begin
if Assigned(FOnColCountChanged) then
FOnColCountChanged(Self);
end;

procedure TMyStrGrid.SetMyColCount(Value: Longint);
begin
ColCount := Value;
MyColCountChanged(Self);
end;

procedure TMyStrGrid.SetOnColCountChanged(const Value: TNotifyEvent);
begin
FOnColCountChanged := Value;
end;

procedure TForm1.ColChanged(Sender: TObject);
begin
with Sender as TMyStrGrid do
ShowMessage('ColCount is changed to ' + inttostr(ColCount));
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
MyStrGrid := TMyStrGrid.Create(self);
MyStrGrid.Parent := self;
MyStrGrid.OnColCountChanged := ColChanged;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
//demo code
MyStrGrid.MyColCount := MyStrGrid.ColCount + 1;
end;

end.
 
我不只需要ColCount,还要RowCount,甚至ColWidth等等,若都多加一个属性岂不太多?我是
希望若用户一改变ColCount的值,我就捕捉到了,然后相应改变我的其他属性.能行吗?
 
一种方案如上:作一个套子公布自己的属性,再转换内部实际的属性,其事件触发容易控制
另一种方案:直接使用原属性,这需要仔细看看VCL的源代码,最好从TCustomGrid继承,
改写你需要控制的属性或事件的处理方法,适当时可以Copy大段的VCL源代码,不过比较
繁一点,而且不小心会破坏了Grid的事件响应和处理机制。

我还是建议第一种,将来TStringGrid升级了,你的控件升级也容易。
 
若没有其他办法,我就准备结束问题了.
 
按照 TStringGrid 的情况,不好在 ColCount 改变时马上得到通知,但你可以用一个方法
包装你的动态数组,在该方法中检查 ColCount 是否已改变,改变则重新分配数组大小,
然后将数组作为方法的返回值,而不是直接访问存储指向该数组指针的字段,就象
TWinControl 的 Handle 属性,在需要的时候才创建一个 Window 并返回窗口的句柄。因此
最好将你的数组作为属性。如:
type
TMyArray = array of double;

TMyStringGrid = class(TStringGrid)
private
...
FMyArray: TMyArray;
function GetMyArray: TMyArray;
property MyArray: TMyArray read GetMyArray;
public
...
end;
implementation
...
function TMyStringGrid.GetMyArray: TMyArray;
begin
if (Length(FMyArray) < ColCount) then
SetLength(FMyArray, ColCount);
Result := FMyArray;
end;

然后只访问 TMyStringGrid.MyArray 属性,而不是 FMyArray 字段,则总能保证数组足够大。
 
同意楼上的方法。
 
dadabox1,我也正在以TStringGrid为基础写一个表格控件,主要实现在CELL中嵌入
Button,ListBox,DropList等功能,很想和你交流一下。Blackbeam@21cn.com.
 
建议你们去看看一些比较成熟的表格控件,或许你要的功能他们已经完成了,
诸如内嵌控件之类什么的。如果考虑以后表格功能扩充的话,建议你还是从上一级
继承,然后重写吧,我就吃过亏,老是想简单了事,结果功能多了,结构变得很混乱,
最后还是自己写。
 
如果你是用stringgrid连接数据库,你可以用数据库的recordcount来更改变
stringgrid的colcount。然后再更改你的数组。
 
多人接受答案了。
 
后退
顶部