Announcement

Collapse
No announcement yet.

Object auf vorhandene Eigenschaft testen?

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Object auf vorhandene Eigenschaft testen?

    Hallo zusammen,

    gibt es eine Möglichkeit in einer Schleife durch verschiedene Objekte zu gehen und jeweils zu testen ob das Object eine bestimmte
    Property besitzt?

    Gruß Andreas

  • #2
    Hi Andreas,

    ich bin mir nicht sicher, ob ich die Frage richtig verstehe, aber hast Du dir schon mal die RTTI (Run Time Type Information) angesehen? Da kannst Du z.B. mit ClassNameIs prüfen, ob ein bestimmtes Objekt eine Instanz einer bestimmten Klasse ist. Wenn Du die Klasse weißt, weißt Du ja auch welche Eigenschaften vorhanden sind. Alle VCL-Klassen unterstützen RTTI, eigene Klassen müssen von TObjekt oder TComponent usw abgeleitet sein, damit die RTTI zur Verfügung steht.

    In der Hoffnung das der BCB und Delphi in dieser Beziehung identisch sind...

    Grüße Joche

    Comment


    • #3
      Danke. Aber das Problem liegt etwas anders.
      Ich habe ca. 40 Forms in der Anwendung, die alle von TForm abgeleitet sind. Einige dieser Fenster haben eine von mir definierte Property
      Mandant (Integer).

      Wenn ein Mandant gelöscht wird sollen alle seine Fenster geschlossen werden.
      Ich will also durch alle geöffneten Fenster der Anwendung, und bei denen die eine property Mandant besitzen diesen mit dem gelöschten vergleichen.

      Gibt es eine Möglichkeit, oder muss ich mir dafür eine eigene Fensterklasse schreiben und die Fenster dann über die RTTI auf diese Klasse testen.

      Gruß Andrea

      Comment


      • #4
        Hallo,

        da will mir nix passendes Einfallen (außer eben eigene Fensterklasse...)

        Aber warum machst Du nicht eine bentzerdefinierte Nachricht (die als Para. die Mandanten-Id enthält) und sendest die an alle Forms Deiner App. In allen Forms, die es betrifft dann eine entsprechende Botschaftsbearbeitung schreiben. Den Parameter auswerten und Fenster gegebenenfalls schließen.

        Sollte funktionieren, weiß bloß nicht, ob es so sinnvoll ist...

        Grüße Joche

        Comment


        • #5
          Hallo,

          wenn es ein übergeordnetes From gibt, könnte man das über die Control-Property lösen.

          etwa so:

          <PRE>
          for i := 0 to MainForm.controlcount -1 do
          begin
          if (Mainform.controls[i] is Tmyform) AND (TMyform(Mainform.controls[i]).mandant = xy) then
          tuwas
          end;

          </PRE>

          hierbei werden nur die Kinder des übergeordeten Forms angesprochen. Das gleiche ginge auch mit Application.components, aber das dürfte ein bisschen viel sein...

          gruß

          Juli

          Comment


          • #6
            Wenn es zu aufwendig ist, eine eigene Vorfahren-Klasse für die Formulare zu verwenden, kannst Du auch die "Tag"-Eigenschaft der betr. Formulare auf einen vereinbarten Wert setzen.

            In der von Julia angegebenen Schleife wäre dann lediglich das "Tag" abzufragen:

            <PRE>
            const
            MagicTag = 12345;
            // Diesen Wert in allen betr. Forms als "Tag" eintragen.

            for i:=0 to MainForm.ControlCount-1 do begin
            if MainForm.Controls[i].Tag=MagicTag then
            tuwas;
            end;
            </PRE>

            Gruß, Werne

            Comment


            • #7
              Hi Andreas,<p>
              schau dir mal die Unit TypInfo an. Da gibt's eine
              Funktion namens GetPropInfo (o.ä.), die dir
              vielleicht helfen kann.
              <p>Ciao, Uli

              Comment


              • #8
                Noch ne Idee: Du könntest ein Interface IHatMandant
                definieren, das aus genau einer Property Mandant
                besteht, und das alle deine Forms, die einen
                Mandanten haben, implemntieren lassen. Dann könntest
                du mit Form.Supports(IHatMandant) testen.
                <p>
                HTH, Uli

                Comment


                • #9
                  Für mich sieht das nach einem typischen Architektur-Problem aus. Ich möchte deshalb hier mal auf MVC (Model-View-Controller) hinweisen. Ganz ähnlich ist das Observer-Pattern, das z.B im Buch "Entwurfsmuster" von Erich Gamma, Richard Helm, Ralph E. Johnson beschrieben wird. Die engl. Ausgabe trägt den Titel "Design Patterns".

                  Würde eine dieser beiden Techniken angewendet werden, dann würde der Mandant die Views(Formulare) kennen, die Inhalte von ihm anzeigen und der Mandant könnte in seinem Destruktor die Views mit zerstören.

                  Das nur mal so als Hinweis. Ich weiß, so was lässt sich im Nachhinein nicht mehr so ohne weiteres implmenentieren, aber beim nächsten Entwurf sollte man vielleicht mal dran denken.

                  Gruß

                  Wolfgan

                  Comment


                  • #10
                    Die Idee mit den Interfaces ist sicher für den Fall die geeignetste. Das solltest Du unbedingt mal testen.<p>
                    Das Problem bei Interfaces ist, dass Delphi dabei standardmäßig die Freigabe der Objekte übernimmt. Das ist praktisch, wenn man es mag und seine Anwendung darauf abgestimmt hat. In einer bestehenden Anwendung ist es aber sicher nicht optimal unterzubringen. Von daher wäre zu prüfen, ob Du diese Logik:<br>
                    http://www.swissdelphicenter.ch/de/showcode.php?id=1875<br>
                    Deiner Anwendung nachträglich unterschieben könntest.<p>
                    Schöne Grüße, Mario Noac
                    Schöne Grüße, Mario

                    Comment


                    • #11
                      Hallo!<br>
                      Wenn ich mal so alle Deine Fragen hier diagonal lese muss ich Wolfgang absolut Recht geben. Extrem schwache Architektur.<br>
                      Du solltest DRINGENDST die Zeit investieren und da etwas Arbeit reinstecken. 40+ Forms und weder eine gemeinsame Basisklasse (oder Interface) noch eine zentrale Verwaltug der offenen Forms.. Das ist Wahnsinn und muss dir früher oder später so richtig heftig um die Ohren fliegen.<br>
                      Spätestens wenn Deine Anwender Erweiterungswünsche an dich herantragen ist Schluss mit lustig...<br>
                      Unser Projekt besteht jetzt mittlerweile aus so ca 150 Formularen. Alle nett in Packages untergebracht eine gemeinsame Basisklasse unterstützt durch Interfaces nach Bedarf. Das Ganze abgerundet mit einer zentralen Verwaltung der offenen und verfügbaren Formulare. Erweiterungen wie Mandanten etc?? Eine Arbeit im Minutenbereich..<br>
                      BYE BERN

                      Comment


                      • #12
                        Noch ist nicht alles verloren, wenn die Forms einigermassen homogen sind, lässt sich auch im Nachhinein noch eine kleine Verwaltung aufbauen (bei inhomogenen Forms ist die Vererbung wohl geeigneter). Nun, zentral heisst über ein Array oder eine Liste, wie es auch das MVC einsetzt:

                        <PRE>
                        const
                        maxForms = 100;

                        var
                        frmController: TForm1
                        frmArray: array[1..maxForms] of TForm;
                        frmRefArray: array[1..maxForms] of TFormClass;

                        implementation
                        uses Unit7; // and all of the units

                        procedure TForm1.btnfrmController(sender : TObject);
                        begin
                        ... // iterating or indexing as you like
                        frmArray[7]:= frmRefArray[7].create(self);
                        frmArray[7].showModal; // whatever you need
                        frmArray[7].mandant:= 1;
                        frmArray[7].free;
                        end;
                        </PRE>

                        Diese Struktur lässt sich dann mit Hilfe der Klassenreferenz iterieren und zusätzliche Properties sind erweiterbar, sofern die Klassen vorgängig reserviert werden:

                        <PRE>
                        unit Unit7;

                        implementation

                        uses frmControllerU;

                        procedure TForm7.FormCreate(sender: TObject);
                        frmArray[7]:= self;
                        end;

                        initialization
                        frmRefArray[7]:= TForm7 //hard coded
                        </PRE>

                        Tip: wenn die Forms bereits instanziert sind, bietet TScreen auch einige Hilfe an:

                        for i:= 0 to screen.FormCount - 1 do
                        if screen.forms[i].className = 'TForm7' then ..

                        Comment


                        • #13
                          Hallo,

                          vielen Dank an alle. Ich habe Eure Ratschläge beherzigt und mir mal (erstmal auf dem Papier) eine Vererbungsskizze meiner Anwendung gemacht.

                          Die Basisklasse ist fertig programmiert und in alle Fenster implementiert. Ich sehe schon jetzt die deutlichen Vorteile.

                          Aber so ist es eben, wenn man mit einer Sprache erst während eines Projektes anfängt und die Anwendung viel komplexer wird, als es zum Anfang abzusehen war.

                          Aber jetzt ist es wirklich höchste Zeit zum Aufräumen.

                          Gruß Andrea

                          Comment

                          Working...
                          X