控件中的控件,为何不能修改属性? ( 积分: 100 )

  • 主题发起人 主题发起人 oliver99
  • 开始时间 开始时间
O

oliver99

Unregistered / Unconfirmed
GUEST, unregistred user!
TEdit里面有一个DBGrid,
为何在属性面板中改DBGrid的属性没用?
下面是一段控件代码,请大家帮帮看看!

unit TextEdit;

interface

uses
SysUtils, Classes, Controls, StdCtrls, DBGrids;

type
TTextEdit = class(TEdit)
private
{ Private declarations }
FDBGrid: TDBGrid;
procedure SetDBGrid(Value: TDBGrid);
protected
{ Protected declarations }
public
{ Public declarations }
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
{ Published declarations }
property DBGrid: TDBGrid read FDBGrid write SetDBGrid;

end;

procedure Register;

implementation

procedure Register;
begin
RegisterComponents('VCL', [TTextEdit]);
end;

constructor TTextEdit.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FDBGrid := TDBGrid.Create(Self);
FDBGrid.Visible := False;
end;

destructor TTextEdit.Destroy;
begin
if FDBGrid <> nil then
begin
FDBGrid := nil;
FDBGrid.Free;
end;

inherited;
end;

procedure TTextEdit.SetDBGrid(Value: TDBGrid);
begin
FDBGrid.Assign(Value);
//FDBGrid := Value;
end;

end.
 
TEdit里面有一个DBGrid,
为何在属性面板中改DBGrid的属性没用?
下面是一段控件代码,请大家帮帮看看!

unit TextEdit;

interface

uses
SysUtils, Classes, Controls, StdCtrls, DBGrids;

type
TTextEdit = class(TEdit)
private
{ Private declarations }
FDBGrid: TDBGrid;
procedure SetDBGrid(Value: TDBGrid);
protected
{ Protected declarations }
public
{ Public declarations }
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
{ Published declarations }
property DBGrid: TDBGrid read FDBGrid write SetDBGrid;

end;

procedure Register;

implementation

procedure Register;
begin
RegisterComponents('VCL', [TTextEdit]);
end;

constructor TTextEdit.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FDBGrid := TDBGrid.Create(Self);
FDBGrid.Visible := False;
end;

destructor TTextEdit.Destroy;
begin
if FDBGrid <> nil then
begin
FDBGrid := nil;
FDBGrid.Free;
end;

inherited;
end;

procedure TTextEdit.SetDBGrid(Value: TDBGrid);
begin
FDBGrid.Assign(Value);
//FDBGrid := Value;
end;

end.
 
你发放的DBGrid属性只能用于设置它为某一个实例的DBGrid而不能操作其属性。。。

这样才能保证它的封装性

如果你需要修改它已经Create的DBGrid属性只能再开放其他属性来控制。。。
例如
Property width : integer read FDBGrid.Width write FDBGrid.Width;
Property ReadOnly : integer read FDBGrid.ReadOnly write FDBGrid.ReadOnly;
 
上面的两个属性是例子。。。如果用了它将覆盖TEdit的这两个属性
 
如果我想把DBGrid当成一个类来用,为何不可以?

DBGrid属性只能用于设置它为某一个实例的DBGrid而不能操作其属性。。。

如何才能操作DBGrid的属性?
 
如果是想使用类似 DBGrid 中使用 DataSource 这样的指向属性,可以使用以下的类似方式:
type
TTextEdit = class(TEdit)
private
FDBGrid: TDBGrid;
procedure SetDBGrid(Value: TDBGrid);
protected
procedure Notification(AComponent: TComponent;
Operation: TOperation); override;
published
property DBGrid: TDBGrid read FDBGrid write SetDBGrid;
end;
.....

//在Create中不用创建。

procedure TTextEdit.SetDBGrid(Value: TDBGrid);
begin
FDBGrid := Value;
if Value <> nil then Value.FreeNotification(Self);
end;

procedure Notification(AComponent: TComponent;
Operation: TOperation);
begin
inherited Notification(AComponent, Operation);
if (Operation = opRemove) and (AComponent = FDBGrid) then
FDBGrid := nil;
end;

具体的例子也可以参考 VCL 中 TCustomLabel类。
 
To:jeffrey_s
不是要这样的
是要像TFont这个属性一样,不过,不需要属性编辑框。
谢谢
 
如果是这样,可以参照 VCL 中 LabeledEdit 类
type
TTextEdit = class(TEdit)
private
FDBGrid: TDBGrid;
protected
procedure Notification(AComponent: TComponent;
Operation: TOperation); override;
public
constructor Create(AOwner: TComponent); override;
published
property DBGrid: TDBGrid read FDBGrid;
end;
.....

constructor TTextEdit.Create;
begin
inherited;
FDBGrid := TDBGrid.Create(Self);
.....
end;

procedure TTextEdit.Notification(AComponent: TComponent;
Operation: TOperation);
begin
inherited Notification(AComponent, Operation);
if (Operation = opRemove) and (AComponent = FDBGrid) then
FDBGrid := nil;
end;
 
是不是想把两控件捆在一起?
一定要在edit.create事件中调用dbgrid.create的,然后就可以用了。
edit1.dbgrid.width:=100
 
TO: jeffrey_s
方法不可行,请帮帮忙啊。
TO:初学者1号
edit1.dbgrid.width:=100
这样是可以的,可是在属性面板里设置,就不行了,写不到*.dfm文件里。

请大家看看啊。。。。。
 
为什么不可行?你自己试试就知道。
type
TTextEdit = class(TEdit)
private
FDBGrid: TDBGrid;
protected
procedure SetParent(AParent: TWinControl); override;
procedure Notification(AComponent: TComponent;
Operation: TOperation); override;
public
constructor Create(AOwner: TComponent); override;
published
property DBGrid: TDBGrid read FDBGrid;
end;

implementation

constructor TTextEdit.Create;
begin
inherited;
FDBGrid := TDBGrid.Create(Self);
FDBGrid.Name := 'SubDBGrid'; { do not localize }
FDBGrid.SetSubComponent(True);
end;

procedure TTextEdit.Notification(AComponent: TComponent;
Operation: TOperation);
begin
inherited Notification(AComponent, Operation);
if (Operation = opRemove) and (AComponent = FDBGrid) then
FDBGrid := nil;
end;

procedure TTextEdit.SetParent;
begin
inherited SetParent(AParent);
if FDBGrid = nil then exit;
FDBGrid.Parent := AParent;
FDBGrid.Visible := True;
end;
完全根据 TLabeledEdit 的风格改编的,不过 里面的 DBGrid在设计期是没有焦点的,有点不方便,就像 LabeledEdit 上的 Label一样。
不过,对于题目,我想这样应该就可以了。
 
oliver99:

真的不明白你的问题, 我照你的代码安装了下, 可以修改!
但是另外一个问题是, 保存了,打开就没有啦,

问题解决方法:
constructor TTextEdit.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FDBGrid := TDBGrid.Create(Self);
[blue] FdbGrid.SetSubComponent(true);[/blue]
FDBGrid.Visible := False;
end;

这样就可以保存到 dfm 文件中
 
TO:jeffrey_s
谢谢了,我想知道,下面一段是什么意思。
procedure TTextEdit.Notification(AComponent: TComponent;
Operation: TOperation);
begin
inherited Notification(AComponent, Operation);
if (Operation = opRemove) and (AComponent = FDBGrid) then
FDBGrid := nil;
end;
 
//VCL 中控件的 加入和删除 都会触发全部的Notification信息
procedure TTextEdit.Notification(AComponent: TComponent;
Operation: TOperation);
begin
inherited Notification(AComponent, Operation); //继承信息,接受Notification
if (Operation = opRemove) and (AComponent = FDBGrid) then
FDBGrid := nil; //当遇到外部删除 FDBGrid时,当前组件取消FDBGrid
//如果不写这句可能会调用错误。
end;
 

Similar threads

后退
顶部