关于 dkDock, 急!(100分)

  • 主题发起人 主题发起人 ll_yybb
  • 开始时间 开始时间
L

ll_yybb

Unregistered / Unconfirmed
GUEST, unregistred user!
我把一个DBEDIT 控件的DragKind 属性设为 dkDock,DragMode设为 dmAutomatic,

再把它放在一个DBCtrlGrid上。调试时发现当我激活这个DBEDIT (指弹出DOCK 框)

输入完数据后,点击 × 按钮,想让它回到 DBCtrlGrid 上时,这个 DBEdit 却消失

了,而且无法再激活或显示, 望赐教!
 
怎莫没人说话?? 急死我了!
再加50分,保证现金支付!!
没有说明白的地方请大家发帖子问。
 
点击 × 按钮,只是把 DBEdit1.Visible 设为 False ,令 DBEdit1.Visible := True 就行了。
 
要完整解决这个问题,只有从 TDBCtrlGrid 源码级去着手。
TDBCtrlGrid 里面隐含了一个 Panel,被 Protected 了,在程序中一般无法直接访问,它是
TDBCtrlGrid 所有数据控件的 Parent 。
protected
property Panel: TDBCtrlPanel read FPanel;
数据控件被 Drag 并关闭之后,令 DBEdit1.Visible := True 可以重新显示,但是要让它们回到
DBCtrlGrid 中,还必须令 DBEdit1.Parent := DBCtrlGrid.Panel;
但是现在问题是,TDBCtrlPanel.Panel 属性是 Protected ,在你的程序里无法直接访问,所以
必须玩一点小技巧。
Object Pascal 语言有一个有意思的特点,就是同一个 Unit 中的 Class 默认都是 Friend ,
就是 C++ 语言的“友元”,“友元”之间可以互相访问 Protected 部分的数据,因此这个问题的
解决办法如下:
class TMyDBCtrlGrid = class(TDBCtrlGrid); // 构造一个新的类,同你的代码写在一个单元中
// 不做任何改动,其实就是 TDBCtrlGrid
procedure TForm1.Button1Click(Sender: TObject);
begin
DBEdit1.Visible := True;
DBEdit1.Parent := TMyDBCtrlGrid(DBCtrlGrid1).Panel; // 强制转换类型,目的是为了访问保护属性 Panel
// 再手工调整一下控件的坐标就行了
end;

Clear ?

From: BaKuBaKu
 
BakuBaku:
你的意思我好像明白了,我用的恰好就是 C++ Builder,我尝试用InsertControl方法使DBEdit
的Parent指向DBCtrlGrid,程序却总是报告AccessViolation错误,不知道为什莫?
 
你的方法同我的解释好象不是一回事。

你为什么会想到用 InsertControl 方法,是自己想出来的,还是哪本书上讲的?我并没有这样说啊!

只要这样就可以了。

class TMyDBCtrlGrid = class(TDBCtrlGrid); // 构造一个新的类,同你的代码写在一个单元中
// 不做任何改动,其实就是 TDBCtrlGrid
procedure TForm1.Button1Click(Sender: TObject);
begin
DBEdit1.Visible := True;
DBEdit1.Parent := TMyDBCtrlGrid(DBCtrlGrid1).Panel; // 强制转换类型,目的是为了访问保护属性 Panel
// 再手工调整一下控件的坐标就行了
end;
当然如果你用 BCB ,需要改写成 C++ 语法。

你的做法倒真的把我搞糊涂了。
 
多谢指教!
 
后退
顶部