带关联的复合组件的published property问题(有难度,cAkk等高手请进) (100分)

  • 主题发起人 主题发起人 Adnil
  • 开始时间 开始时间
A

Adnil

Unregistered / Unconfirmed
GUEST, unregistred user!
TMyEdit是一个TEdit和一个TUpDown的组合,Create构造函数大致如下:
FEdit := TEdit.Create(Self);
FEdit.Parent := Self;
FUpDown := TUpDown.Create(Self);
FUpDown.Parent := Self;
FUpDown.Associate := FEdit;

注册组件后发现Edit的属性被存储了两次,dfm文件如下:
object MyEdit1: TMyEdit
Left = 252
Top = 256
Caption = 'MyEdit1'
TabOrder = 1
Edit.Left = 0
Edit.Top = 0
Edit.Width = 60
Edit.Height = 16
Edit.TabOrder = 0
Edit.Text = '0'
UpDown.Left = 60
UpDown.Top = 0
UpDown.Width = 16
UpDown.Height = 16
UpDown.Associate.Left = 0 //为什么Associate的属性又保存了一遍?
UpDown.Associate.Top = 0
UpDown.Associate.Width = 60
UpDown.Associate.Height = 16
UpDown.Associate.TabOrder = 0
UpDown.Associate.Text = '0'
UpDown.Min = 0
UpDown.Position = 0
UpDown.TabOrder = 1
UpDown.Wrap = False
end
 
你的组件写的有问题吧
 
to chenhaipeng: 请指出有什么问题?
 
FUpDown.Associate := FEdit;
这句去掉试一试。
 
FEdit := TEdit.Create(Self);
FEdit.Parent := Self;
FUpDown := TUpDown.Create(Self);
FUpDown.Parent := Self;
FUpDown.Associate := FEdit;
//怎么能用Self呢
最好是把Edit和UpDown放到Panel上
TmyEdit=class(TPanel)
如果采用TmyEdit=class(TEidt)的话有两种方法:
1.override setwidth,setparent,setLeft...
2.override doPaint;要自已画图
 
忘了说了,我现在用的就是
TmyEdit=class(TPanel)
...
end;

to savenight:
这句话不能去掉,去掉的话去失去组合的功能了。
 
savenight,去掉就成了两个独立的控立的构件了
 
試一試
FUpDown := TCustomUpDown.Create(Self);
成不成,不成的話﹐就沒辦法了
 
Associate是published的属性当然要保存了。
 
Associate只是一个对象的引用,按理应该生成
UpDown.Associate = Edit

还请这方面熟悉的dfw赐教。
 
把你的控件发过来我看看,savenight@sohu.com
 
TMyEdit = class(TPanel)
private
FEdit: TEdit;
FUpDown: TUpDown;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
property Edit: TEdit read FEdit;// write FEdit;
property UpDown: TUpDown read FUpDown;// write FUpDown;
property BevelOuter default bvNone;
property BorderStyle default bsSingle;
property Width default 80;
property Height default 20;
end;

procedure Register;

implementation

procedure Register;
begin
RegisterComponents('Adnil', [TMyEdit]);
end;

{ TMyEdit }

constructor TMyEdit.Create(AOwner: TComponent);
begin

inherited;

Caption := '';
BevelOuter := bvNone;
BorderStyle := bsSingle;

FEdit := TEdit.Create(Self);
FEdit.SetSubComponent(True);
FEdit.BorderStyle := bsNone;
FEdit.Height := 16;
FEdit.Width := 60;
FEdit.Parent := Self;

FUpDown := TUpDown.Create(Self);
FUpDown.SetSubComponent(True);
FUpDown.Parent := Self;
FUpDown.Associate := FEdit;

Width := 80;
Height := 20;

end;

destructor TMyEdit.Destroy;
begin
FEdit.Free;
FUpDown.Free;
inherited;
end;
 
不會啊﹐我試后的 dfm 文件如下
object MyEdit1: TMyEdit
Left = 112
Top = 80
Width = 121
Height = 65
Caption = 'MyEdit1'
TabOrder = 0
end
不過我屏蔽
FEdit.SetSubComponent(True);
FUpDown.SetSubComponent(True);
這兩個方法﹐因為我編譯不通過﹐ 不知道這兩個方法是那里來的?


 
你的属性编辑器根本就看不到Edit和UpDown,当然就什么都没有了.
Setsubcomponent方法请见Delphi帮助。
 
沒有 Setsubcomponent 啊﹐我用文件搜索來找delphi的所有源碼
都沒有找倒這個方法,難道是 delphi6 新增的﹐用來做什么的?

我是照你的代碼編譯的﹐属性编辑器可以看倒Edit和UpDown,不過沒什么用﹐就是顯示
MyEdit1. 這几個字﹐又改不了
 
应该是新增的了,声明为subcomponent后可以在property editor中编辑,包括属性和事件。
 
又學倒一招﹐不過那就沒辦法了
你既要可以在property editor中編輯它﹐又要dfm中不保存它的信息﹐
那在 property editor中編輯的后的信息保存在那里?你這不是難為delphi 嗎?

你只有自己寫一個不保存 Associate 對象信息的 updown 控件啦
 
请你先看懂我的代码,不是不要保存,而是Delphi保存了两遍。
Associate对象其实就是Edit对象。

Edit.Left = 0
Edit.Top = 0
Edit.Width = 60
Edit.Height = 16
Edit.TabOrder = 0
Edit.Text = '0'
UpDown.Associate.Left = 0
UpDown.Associate.Top = 0
UpDown.Associate.Width = 60
UpDown.Associate.Height = 16
UpDown.Associate.TabOrder = 0
UpDown.Associate.Text = '0'
理论上Delhpi只需生成
Edit.Left = 0
Edit.Top = 0
Edit.Width = 60
Edit.Height = 16
Edit.TabOrder = 0
Edit.Text = '0'
UpDown.Associate = Edit
...
...
即可。
 
我估計 SetSubComponent 是的 bug
它把控件每一層的對象的屬性都保存了
 
后退
顶部