2010-10-11 60 views
2

我一直在Delphi 2009中开发一个程序。它与物化的程序“Mimics”非常相似,您可以在其中创建和操作3D网格。有4个面板用于查看3D对象(XY,YZ,XZ和3D透视图)。每个面板都是我为查看3D对象而制作的自定义框架的一个实例。然后将4个面板装载到具有按钮和其他部件的窗体上。窗体和框架之间的通信

我遇到的一个问题是,框架必须访问它们所在窗体的子例程。例如。如果我改变其中一个框架中的网格物体的某些内容,则应更新(刷新)所有框架,这是父窗体中可用的过程。但要调用父窗体上的过程,我必须将父窗体的单元文件包含在3D框架的实现使用子句中。这很好,而且这一般没有任何麻烦。问题是我不能使用父窗体继承。如果我从父窗体创建继承类,则单元名称和窗体名称会发生​​更改,然后我必须更改3D框架以引用此新的更改窗体。

这真的是我的问题的关键。我不知道如何从其子框架引用父窗体的属性,而不明确指出窗体的名称。我希望能够重用和扩展父窗体,但是我没有看到如何改变窗体使用的3D框架。

任何帮助将不胜感激。谢谢。

回答

9

所以你有一个独立的组件(一个框架),必须能够从它所放置的表单调用代码,而不需要编译时知道表单本身?听起来很像一个TButton,它不知道当你点击它时,如何处理它的表单,解决方案是一样的:使用事件处理程序。将OnChangeMes​​h(或类似的东西)事件属性添加到您的框架,并让您的窗体在创建框架时分配适当的方法。

+0

非常感谢您的回复。我现在明白,事件处理程序将允许我从该表单的框架调用父表单的子例程,这是我解决我的问题的方法,正如我所说的那样。我想知道是否还可以从子框架中更改父表单的数据字段。例如。如果我在其中一个框架中对网格进行切片,我想更新网格的可见边界,这是父窗体的一个属性。 – Nicholas 2010-10-11 22:21:52

+2

您可以拥有的活动数量没有限制。您可以让您的框架引发一个事件,然后让父表单从框架中读回,相应地更新属性,然后根据需要将这些属性更改传播给其他框架。 – Jenakai 2010-10-11 22:49:55

3

您可以使用订阅结构。维护视图框架的全局列表。如果帧需要更新,则简单地遍历该列表并针对每帧帧调用updae过程。这可以让你有1,2或100帧更新,如果事情已经改变。

如果你想去所有的面向对象,并真的很高兴:这是观察者模式。

http://en.wikipedia.org/wiki/Observer_pattern

6

另一种选择可以是定义母体形式实现的接口。它应该有所有的属性和你想从你的孩子帧访问方法是这样的:

ImyFormInterface=interface 
['{08BD9B3C-C48E-47B7-AE67-279277C7E024}'] 
    function GetValue1: integer; 
    function GetValue2: integer; 
    procedure SetValue1(val: integer); 
    procedure SetValue2(val: integer); 

    procedure SomeMethod; 
    function GetSomeValue: integer; 


    property Value1: integer read GetValue1 write SetValue1; 
    property Value2: integer read GetValue2 write SetValue2; 
end; 

然后,让你的主要形式,实现该接口:

TForm1 = class(TForm, ImyFormInterface) 
private 
    { Private declarations } 
public 
    // Implement ImyFormInterface 
    function GetValue1: integer; 
    function GetValue2: integer; 
    procedure SetValue1(val: integer); 
    procedure SetValue2(val: integer); 

    procedure SomeMethod; 
    function GetSomeValue: integer; 
public 
    { Public declarations } 
end; 

然后在你的框架,你可以使用类似的东西:

procedure Tframe1.Button1Click(Sender: TObject); 
var pform: TcustomForm; 
i: ImyFormInterface; 
begin 
    pform:=GetParentForm(self); 
    if (pform.GetInterface(ImyFormInterface, i)) then 
    begin 
    i.SomeMethod; 

    i.Value1:=i.Value1+10; 

    Self.SomeProperty:=i.GetSomeValue; 
    end; 
end; 

现在,如果您从父窗体继承,它将仍然工作,因为您仍然可以获得界面。此外,你可以把你的框架放在一个全新的窗体上,只要新窗体实现了界面,那么它也可以在那里工作。

0

最终的解决方案可能是签出可视化表单/框架继承。

可以从基础框架和基础框架中派生窗体。将虚拟方法添加到baseframe并在继承版本中覆盖它们。

相关问题