2010-10-11 5 views
2

J'ai travaillé sur un programme dans Delphi 2009. Il est très similaire au programme "Mimics" par matérialiser, où vous pouvez créer et manipuler des maillages 3D. Il y a 4 panneaux avec des aspects différents pour visualiser un objet 3D (XY, YZ, XZ et perspective 3D). Chacun des panneaux est une instance d'un cadre personnalisé que j'ai créé pour visualiser des objets 3D. Les 4 panneaux sont ensuite chargés sur une forme qui a des boutons et d'autres composants.Communication entre les formes et les cadres

Un problème que je rencontre est que les cadres doivent accéder aux sous-routines du formulaire sur lequel ils résident. PAR EXEMPLE. Si je change quelque chose sur le maillage im dans l'un des cadres, TOUTES les images doivent être mises à jour (actualisées), ce qui est une procédure disponible dans le formulaire parent. Mais pour appeler des procédures sur le formulaire parent, je dois inclure le fichier d'unité du formulaire parent dans la clause uses d'implémentation du cadre 3D. C'est bien, et cela fonctionne en général sans aucun problème. Le problème est que je ne peux pas utiliser le formulaire parent pour en hériter. Si je crée une classe héritée à partir du formulaire parent, le nom de l'unité et le nom du formulaire changent et je dois alors modifier le cadre 3D pour faire référence à ce nouveau formulaire modifié.

C'est vraiment le noeud de mon problème. Je ne sais pas comment référencer les attributs d'un formulaire parent à partir de ses cadres enfants sans indiquer explicitement le nom du formulaire. Je veux être en mesure de réutiliser et de développer sur le formulaire parent, mais je ne vois pas comment c'est possible sans changer aussi les cadres 3D qui sont utilisés par le formulaire.

Toute aide serait grandement appréciée. Je vous remercie.

Répondre

9

Vous avez donc un composant autonome (un cadre) qui doit être capable d'invoquer du code à partir du formulaire sur lequel il est placé, sans avoir la connaissance à la compilation du formulaire lui-même? Ressemble beaucoup à un TButton qui ne sait pas quoi faire avec le formulaire sur lequel il est quand vous cliquez dessus, et la solution est la même: utilisez un gestionnaire d'événements. Ajoutez une propriété d'événement OnChangeMesh (ou quelque chose comme ça) à votre cadre et demandez à votre formulaire d'affecter la méthode appropriée lorsqu'il crée les cadres.

+0

Merci beaucoup pour la réponse. Je comprends maintenant que les gestionnaires d'événements me permettent d'appeler les sous-routines du formulaire parent à partir de la trame de ce formulaire, et c'est une solution à mon problème comme je l'ai dit. Je voudrais savoir s'il est également possible de modifier les champs de données du formulaire parent à partir des cadres filles. PAR EXEMPLE. si je fais une tranche du maillage dans l'un des cadres, je voudrais mettre à jour les limites visibles du maillage, qui est une propriété du formulaire parent. – Nicholas

+2

Il n'y a pas de limite au nombre d'événements que vous pouvez avoir. Vous pouvez demander à votre cadre de déclencher un événement, puis de relire le formulaire parent à partir du cadre, de mettre à jour les propriétés en conséquence, puis de propager éventuellement ces modifications de propriété aux autres cadres si nécessaire. – Jenakai

3

Vous pouvez utiliser une structure d'abonnement. Maintenir une liste globale des cadres de vue. Si les trames doivent être mises à jour, faites simplement une boucle sur cette liste et appelez la procédure updae pour chacune des trames. Cela vous permet de mettre à jour 1,2 ou 100 images si quelque chose a changé.

Si vous voulez passer tous les POO et en être très heureux: c'est le modèle d'observateur.

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

6

Une autre option peut être de définir une interface que les outils de forme mère. Il devrait avoir toutes les propriétés et les méthodes que vous souhaitez accéder à partir de votre cadre enfant, quelque chose comme:

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; 

ensuite faire votre principale forme de mettre en œuvre cette interface:

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; 

Ensuite, dans votre cadre, vous pouvez utiliser quelque chose comme:

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; 

maintenant, si vous héritez de votre formulaire parent, il fonctionnera tout encore parce que vous obtiendrez toujours l'interface. En outre, vous pouvez mettre vos cadres sur une forme entièrement nouvelle et tant que cette nouvelle forme implémente l'interface, elle fonctionnera aussi.

0

Une solution finale pourrait être de vérifier la forme visuelle/l'héritage du cadre.

Il est possible de dériver des formulaires à partir d'une baseform et de trames à partir d'une base. Ajoutez des méthodes virtuelles à l'image de base et remplacez-les dans les versions héritées.

Questions connexes