300看问题 + 300回答问题 = 600 (2)(300分)

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

Another_eYes

Unregistered / Unconfirmed
GUEST, unregistred user!
同问题LID=162610.
只是要求不同:
例子:
TNoUsage = class(TPanel)
private
FClient: TPanel;
protected
procedure DefineProperties(Filer: TFiler); override;
procedure ReadClient(Reader: TReader);
procedure WriteClient(Writer: TWriter);
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
property Client: TPanel read fclient stored true; //如果不用defineproperties
// 将其定成自定义property则client属性
// 根本不保存在dfm中.
end;

constructor TNoUsage.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FClient := TPanel.Create(Self); // 出于特殊要求, 需要TNoUsage
// 包含一个单独的Client区域.
// 设计时所有放到TNoUsage中的
// 控件都放到Client中.
FClient.Parent := self;
FClient.Align := alClient;
FClient.Visible := true;
end;

destructor .....

procedure TNoUsage.DefineProperties ....
begin
inherited DefineProperties(Filer);
Filer.DefineProperty('Client', readClient, WriteClient, true);
// filer.DefineBinaryProperty('Client',readclient, writeclient, true); ??????

end;

procedure TNoUsage.ReadClient(Reader: TReader);
begin
fclient := TPanel(reader.readcomponent(nil)); // Stream read error
// FClient := TPanel(reader.readRootComponent(FClient));// same error
// FClient := TPanel(reader.readComponent(fclient)); // same error
// ????????
end;

procedure TNoUsage.WriteClient(Writer: TWriter);
begin
writer.writecomponent(fclient);
// writer.writerootcomponent(fclient); // no effect;
end;

end.
运行环境: Delphi 5
问题: 设计时放到TNoUsage中的所有控件均无法保存到dfm中,
view as text时根本没有client属性. 再次view as form时client中所有
控件消失. 但在.pas中却生成了相应变量. 因此再次打开时将出现错误

尝试手段: 1. 将FClient转成client 属性并公布到published中. 无效
2. 自定义了client类型(defineproperties). 如果定义成BinaryProperty.
则view as text可以看到 dfm中的client属性, 其值是一串奇怪的十六进
制数.再次view as form则client中包含的控件已消失.
如果定义成property, 用TReader, TWriter读写则根本无法保存dfm.
3. 将FClient.Create(self)改成FClient.Create(AOwner)则可以保存
client中的控件. 但view as text发觉生成了4个(?!) client属性, 其中最后
一个client下有其他控件的定义. 而且设计时可以选中fclient(也可以delete它, 这和我的要求完全背道而弛了).
请教:
如何达到我的要求? 即: 我的控件中包含一个动态生成的容器, 设计
时可以将其他vcl放置到这个容器中(以这个容器作为parent, 这个可以
做到), 并且能够保存(实在想不出办法).
 
刚在深度历险找到一个东东,可以“很方便的制作由一个以上现有构件组合而成
的复合构件”,说不定与你的问题有点沾边。(我正在下载,这几天我这里的网
络速度实在是太慢了)
 
Another_eYes真富有。
 
TNoUsage = class(TPanel)
private
FClient: TPanel;
...

TNoUsage本来就是一个TPanel,为何还要定义FClient呢?
 
too difficult
 
1、要直接保存属性不能用public,只能用published,我已经上过当了。
并且这个属性并不是一个控件,而是form上一个控件的值。
用create(aOwner)时,其实时在form上生成控件,所以能够直接修改控件的值,并且
一旦生成后就属于form管辖,在view form是所有的控件都撤消了,在view form时
又做了一次create,所以会多出一堆控件来。
// 所以除非象我上次做的一样,过滤掉loading(比如view as form)时的建立过程 //
// 否则不要在控件的create中使用 xxxx.create(AOwner); //
假如你做的控件要能修改容器中控件的值的话,你只有两条路可以走,一个是做一个
PropertiesEdit,一个是你必须小心的管理建立Form上的控件。
假如你不需要修改容器内值的话,直接xxx.create(self)就可以了
事实我觉得你是在如下的事情:管理放到你控件上的控件,并维持他们可以编辑,并且
parent是你的控件。
现在我的问题是你要自己生成内部的控件还是其它人放控件上去。
如果他人放上去,你不用那么麻烦,Tpanel本来就已经是这样了。
如果要自己create的话,象我那样做,并且连内部的那些Aedit之类的不应该有,
保存应该由form完成,你做是多余的,你可以检查一下所有的控件他们的parent是否
是你,否则就冗余了。当然你实在想保存这个列表的话,可以用TList来保存,因为
如果要可编辑,控件一定在form上!!
 
再说一点,由于你是用create(Aowner)的,在form上已经有这个控件了,也就是说
form本身也会写一次这个控件到dfm里去,所以决不能用WriteComponent.
可以的话可以用WriteString,记录下那个控件的名字。
 
你是不是想做想3dmax一样的可以在里面拉来拉去的控件,我有一个,从一个大控件
库里挖出来的。看了看不难。
 
另一只眼的问题怎么这么长。
 
看看高手的问题
 
呵呵, Energy的回答有点象了. 但是还是没明白我的要求。
我是要design时用户将控件放到我的控件中.
但是有一点点区别:
design时别人放上来的vcl的parent<strong>不是 TNoUsage, 而是TNoUsage.Client</strong>
1. 这个Client必须是<strong>事先</strong>内建在TNoUsage中的.
<strong>是TNoUsage的一部分</strong>, 对用户是透明的(不允许用户修改
这个Client的属性). 因此只能用FClient.Create(self)建立. 不能用FClient.Create(AOwner)
那样这个FClient就可以由用户修改(甚至删除)了.
因此关于componenteditor或者propertyeditor的想法无效.
2. TNoUsage使用时用户似乎是在往TNoUsage中放的其他vcl, 但实际上
这些vcl需要放在TNoUsage.Client中.
比如用户放了一个Edit1到我的TNoUsage中, 实际上Edit1.parent := TNoUsage.Client.
3. 问题是这样处理之后TNoUsage.Client中放置的任何vcl在保存时都无法
存入.dfm中.
4. 关于怎样在一个控件中允许放置其他控件的方法我知道, 而且并不麻烦
(事实上只要一句话). 但是这和我的问题无关.

另: Energy请快到LID=166302去报个到, 我好结束问题.
 
hehe, 问题解决了.
多谢各位关心.
权做送分吧.
明日此时结束问题.
 
多人接受答案了。
 
后退
顶部