Mehrere Instanzen eines Fensters

Ich möchte das gleiche Fenster beliebig oft öffnen und auf jedem arbeiten können.
Das ist erst mal kein Problem, ich deaktiviere “Implicit Instance” des Fensters und erstelle dann jeweils mit

dim w as new window

eine neue Instanz des Fensters.

Wie frage ich jetzt aber z.B. einen Wert auf dem aktiven Fenster in eine Methode außerhalb des Fensters ab?

Du kannst alle öffentlichen Eigenschaften eines Fensters über seinen Namen bestimmen – in dem Fall also
myOtherProperty = w.width oder ähnliches. Oder umgekehrt eben auch aus dem Fenster heraus: my.myproperty = otherclassinstance.property.

Es könnte ratsam sein, die Handles der Fenster in einem Array zu halten, damit du nicht immer erst den entsprechenden Handle suchen musst.

Du erstellst ja jedes neue Fenster mit dim w as new winMain, von daher ist es erst Mal nicht verständlich wie man bei mehreren Fenstern das richtige nimmt.

Dazu die Frage von wo die externe Methode aufgerufen wird.

Sagen wir mal von einem PushButton auf dem Fenster, oder einem Menu.

Dann würde im Action event des PushButton bzw im MenuHandler der Aufruf der Methode stehen.

Wär es nicht schick wenn man der Methode gleich sagen kann welches Fenster?

Das geht! Gib der Methode einen Parameter: CallingWindow as winMain (oder wieimmer dein Window heißt).

Und im winMain rufst du deine Methode dann im PushButton bzw MenuHandler mit MyMethod(self)

Denn self ist immer das aktive Window auf dem die Action stattfindet.

In der Methode kannst du dann CallingWindow ganz normal verwenden, zB

Dim s as wtring
S = CallingWindow.textArea1.text

Wobei sich hier die Frage stellt: muß man das Window als Parameter übergeben, oder gäbe man nicht besser nur den Text weiter?

verstehe gerade die Frage und das Codebeispiel nicht…

Du hast ein Fenster mit dem Namen MyWindow

Dann instantiierst Du es so:

dim w as new MyWindow w.Show

Um auf globale Funktionen Variablen zuzugreifen verwende ich entweder den app Namespace (app.Propertyname = irgendwas) oder nutze eigene Objekte, die mit jedem Fenster mit instantiert werden.

[quote=164568:@Tomas Jakobs]verstehe gerade die Frage und das Codebeispiel nicht…

Du hast ein Fenster mit dem Namen MyWindow

Dann instantiierst Du es so:

dim w as new MyWindow w.Show .[/quote]
Und was wenn du mehr als ein MyWindows hast? Oder arbeitest du in Word auch immer nur mit einem Fenster (Dokument)?

Stell dir vor dein Code ist in einem Menü mit dem Namen “Neues Dokument”

Jedesmal wenn du das Menü aufrufst läuft dein Code, und all die Fenster sind für dich identisch. Wie unterscheidest du sie? Indem du “w” rufst?

Um die Fenster zu unterscheiden brauchst du eine Referenz, und am einfachsten ist das Fenster selbst als Referenz zu verwenden.

bei mehr als nur einem Fenster dann nimmst Du eben weitere Vars:

[code]dim a as new MyWIndow
dim b as new MyWindow
dim c as new MyWindow

a.show
b.show
c.show[/code]

und als Referenz nimmst Du den WIndows.Handle oder fragst explizit die Objekte auf Existenz (<> nil) ab

Willst du wirklich jedesmal drei Fenster aufmachen wenn du das Menü " Neues Dokument" auswählst? :wink:

Ja das macht manchmal je nach Fall Sinn. In Minicalc meiner Softwarelösung für Bauunternehmungen z.B., lasse ich die Stammdaten Fenster von Kontakten in mehreren Fenstern öffnen, damit diese vom Benutzer auch nebeneinander geschoben und Registerblatt für Registerblatt miteinander verglichen werden können. Auch ein Word oder Excel öffnet für jedes neue Dokument ein neues eigenständiges Fenster. Früher in Win3 Zeiten sogar als MDI innerhalb des Hauptfensters…

aber zurück zum Topic: Stefan ist Deine Frage soweit beantwortet? Wie eingangs erwähnt wird mir zumindest nicht klar, was Du genau wolltest…

Also um das nochmal griffiger zu erklren.
Ich habe mehrere instanzen eines Fenster offen, auf dem Fenster kann man nach einer Adresse suchen, man gibt einen Suchtext ein und bekommt das Ergebnis in einem Modal angezeigt. Ich whle dort einen Eintrag aus und dieser soll nun in dem Fenster eingetragen werden, aus dem die Suchabfrage kam.
Das klappt leider noch nicht…
Ich msste also sagen knnen setze den Text im Fenster mit der Instanz Nr. 10 ein… oder im Frontmost

Sorry, aber das ist nicht das was dein Code macht. Dein Code öffnet JEDES MAL wenn du EIN neues Dokument willst DREI Fenster für DREI Dokumente.

Dann mach das so wie ich es beschrieben hab :wink:

Sagen wir du hast zwei Fenster

winAddress
winShowSearchResult

dann hat winAdress einen
Button “Search”
Suchmethode
Array zum Speichern der Ergebnisse, zB SearchResults() as Adress
SetAdress Methode zum Anzeigen der ausgewhlten Adresse (die den index der im Array gewhlten Methode als Parameter nimmt)

Die Suchmethode speichert die gefundenen Adressen in SearchResults

Das winShowSearchResult hat einen Constructor (das ist eine Methode die automatisch luft wenn ein Objekt erzeugt wird)
Constructor(ParentWindow as winAdress) <- am Besten als WeakRef

Zum Anzeigen rufst du dann das winShowSearchResult mit
dim w as new winShowSearchResult( self )
w.show oder w.showModal

winShowSearchResult hat nun das Fenster das es erzeugt hat in ParentWindow gespeichert

In einer ListBox auf winShowSearchResult zeigst du winAdress.SearchResults an

for i as integer = 0 to winAdress.SearchResults.ubound
me.addRow theAdress
next

Die ausgewhlte Adresse kannst du dann mit ParentWindow.SetAdress( ) setzen

Easy peasy.

P.S. Zu WeakRef: Das hab ich in einer Tips&Tricks Kolumne in xDev geschrieben:

Combining a computed property with a weak reference

I love it when something keeps annoying me and I wonder “wouldn’t it be possible to …” and then one of the great Xojo minds comes along and writes a tip or blog post about the question I thought about. It means I’m finally starting to ask the right questions!
There was an excellent tip on Christian’s MBS Blog (http://www.mbsplugins.de/ - if it isn’t on your reading list yet then it should really be as many tips are not specific to his MBS plugins): “Using computed property with weak reference”

Often we need to keep a property somewhere, but it needs to be a weak reference or we run the risk of making circular references and leaking memory in our app. A common example is when we need to keep a reference to a parent window. If the target (e.g. another window) has a reference to the parent, and the parent has a reference to the target, then trying to close the target will not release the reference! But we need the reference to become Nil when the target goes out of scope.

But using a WeakRef is also cumbersome and makes the code look ugly as we need to keep the WeakRef in mind when we access the reference: we can’t simply say “ParentWindow =” or “= ParentWindow” but we need to say WeakRef( ParentWindow) and ParentWindow.Value.

It is much nicer to wrap it in a computer property. This way the compiler can check types when using the property. Internally we map back to the weakRef object like this:

ComputedProperty ParentWindow As window1 Sub Set(value as ParentWindow) if value<>Nil then mParentWindow = new weakref(value) else mParentWindow = nil end if End Function Get() as ParentWindow if mParentWindow<>nil then dim o as variant = mParentWindow.Value Return o end if End End ComputedProperty Property Private mParentWindow As WeakRef
As you see we have a private property with the actual weakRef. The computed property getter checks if we have a WeakRef and provides the value of it. We use a variant to avoid the need of explicit casting. For the setter we either set our weakRef property to nil or a new weakRef pointing to the target value.

Please use weak references always for references in data structures where a leaf references back to the tree.

[quote=164832:@Markus Winter]Dann mach das so wie ich es beschrieben hab :wink:

Sagen wir du hast zwei Fenster

winAddress
winShowSearchResult

dann hat winAdress einen
Button “Search”
Suchmethode
Array zum Speichern der Ergebnisse, zB SearchResults() as Adress
SetAdress Methode zum Anzeigen der ausgewählten Adresse (die den index der im Array gewählten Methode als Parameter nimmt)

Die Suchmethode speichert die gefundenen Adressen in SearchResults

Das winShowSearchResult hat einen Constructor (das ist eine Methode die automatisch läuft wenn ein Objekt erzeugt wird)
Constructor(ParentWindow as winAdress) <- am Besten als WeakRef

Zum Anzeigen rufst du dann das winShowSearchResult mit
dim w as new winShowSearchResult( self )
w.show oder w.showModal

winShowSearchResult hat nun das Fenster das es erzeugt hat in ParentWindow gespeichert

In einer ListBox auf winShowSearchResult zeigst du winAdress.SearchResults an

for i as integer = 0 to winAdress.SearchResults.ubound
me.addRow theAdress
next

Die ausgewählte Adresse kannst du dann mit ParentWindow.SetAdress( <index der gewählten Adresse> ) setzen

Easy peasy.[/quote]

Fast Easy peasy (-:

Das mit dem Constructor scheint nicht zu klappen, da habe ich wohl etwas falsch gemacht.

parentwindow.setadress(textstring) <= This item does not exist

Wie sieht denn der Constructor als Code aus, wenn ich ihn anlege steht da:

Sub Constructor(ParentWindow as ckWindow)
// Calling the overridden superclass constructor.
Super.Constructor

End Sub

Du must das ParentWindow ja auch irgendwo speichern, da die Variable nur im Constructor existiert und anschlieend futsch ist.

Also eine Variable ParentWindow as ckWindow zu winShowSearchResults hinzufgen

Und Constructor ist dann:

Sub Constructor( CallingWindow as ckWindow)
ParentWindow = CallingWindow
// Calling the overridden superclass constructor.
Super.Constructor

Sorry, htte ich ausfhrlicher sein sollen.

Easy Peasy … danke, klappt!

Example project at https://dl.dropboxusercontent.com/u/992591/Xojo/Forum/WindowCommunication.rbp.zip

Schön. Dann bitte Thread als beantwortet markieren :wink:

@Markus: Fein, sehe dass sich das zwischenzeitlich erledigt hat. Und nein natürlich mache ich das nicht so wie in meinem Beispiel geschrieben mit a.b.c sondern jedesmal mit einer neuen Instanz ein und des gleichen Objektes…

Hätte mich auch gewundert. Ich hab dich eher als advanced user im Kopf, jedenfalls deutlich mehr advanced als ich :wink: