Problem mit ContainerControl

Hallo,

ich habe ein Problem mit Containern:
Ich erzeuge dynamisch in einem PagePanel jeweils das gleiche ContainerControl (CC). Dieses zeigt jeweils eine Datenbanktabelle an und besteht somit aus visuellen Komponenten aber auch aus Methoden. Alles funktioniert wunderbar solange man sich innerhalb des CC bewegt. Ich habe versucht, von einer Toolbar aus, die im Elternfenster definiert wurde, auf das jeweilige CC zuzugreifen. Das gelingt aber nicht.

Nun meine Frage:
Wie ist es möglich das aktuell sichtbare CC herauszufinden und darauf zuzugreifen. Über Window.Control(i).Name bekomme ich immer den gleichen Namen angezeigt. Ich möchte aus dem aktuellen Fenster heraus (z.B. nach drücken eines ToolButtons in der ToolBar) auf Methoden und Komponenten des CC zugreifen. Ein Cast MyCC(Window.Control(i)) ist nicht möglich.

Vielleicht hat ja jemand eine Idee…

Beste Grüße aus Köln
Michael O.

Anbei sende ich ein Bild, damit das vielleicht klarer ist:

Leg dir doch eine Referenz zum Container ab im Fenster, wenn du ihn erzeugst. Das wre das einfachste.

Du meinst als Array wie z.B. DIM MyCCArr as MyCC? Habe ich auch schon dran gedacht. Problem ist, dass man die CC auch schliessen kann. Siehe Eject-Button oben. Dann stimmt die Referenz-Nr. nicht mehr mit PagePanel.Value überein. Auch ist mir der Speicherbedarf nicht ganz klar. Erzeuge ich dann nicht einen weiteren Container? Ich werd das aber erst mal probieren.

du kannst weak references nehmen.
bzw. der Container kommt ja im Close Event per TrueWindow an sein Fenster ran und kann sich abmelden.

Teil des Problems ist da beim Klick in die Seitenleiste jedesmal ein neuer ContainerControl erzeugt wird - das ist nicht ntig, nur der erste Klick sollte eines erzeugen. Die Referenz dazu mut du speichern (zB in einem Array) und greifst darauf zu.

Ich wei nicht wie du die Seitenleiste speicherst, aber jeder der Eintrge knnte eine Container-Referenz als Property bekommen. Also so etwas in der Art:

Seuitenleisten-Eintrag wird erzeugt -> neuer Container wird erzeugt -> wird als Property des Seitenleisten-Eintrags gespeichert.

Alternativ:

Seuitenleisten-Eintrag wird erzeugt -> neuer Container wird erzeugt -> wird im ContainerArray des Fensters gespeichert.

Erzeuge ich dann nicht einen weiteren Container?

Nur wenn du jedesmal einen neuen Container mit NEW erzeugst statt einfach die Referenz zum Alten zu verwenden.

Dann stimmt die Referenz-Nr. nicht mehr mit PagePanel.Value berein

Warum eine Nummer als Referenz? Vor allem eine (PagePanel.Value) die sich ndert? Das ist noch das “alte” Denken :wink:

Warum nicht einfach den Container selbst als Referenz? Ich hab immer noch Schwierigkeiten mit der “Objektorientierung” aber mir scheint man erspart sich viel wenn man hier die Objekte (= Container) selbst nimmt statt eine Integer Variable die schnell “out of sync” geraten kann. Im wirklichen Leben begrt du ja auch Thomas, Anne, und Gerd direkt, ohne erst eine Nummer nachzuschauen die du fr jeden gespeichert hast.

Unter Umstnden mut du jedesmal ber das Array gehen und die Eintrge vergleichen um den richtigen Container rauszufischen, aber das geht schnell.

Ich habe das mit einem Dictionary gelöst:

[code]Dim UniqueIdentifierString As String = “MeinContainer”
Dim meinCC As New ContainerControl
Dim buttonDict As New Dictionary

buttonDict.Value(UniqueIdentifierString, meinCC)[/code]

Dann kann man per UniqueIdentifierString bequem abrufen.

PS. Wie hast Du Dein Seitenleistenmenue (Karteikarten, Personen, Belege …) aufgebaut? Ist das eine Listbox?

Besten Dank für die Tipps. Ich habe das Problem ebenfalls umschifft mit Dictionaries und einem Array für die ContainerControls (aContArr unten). Funktioniert jetzt alles wie gewünscht. Beim löschen wird das CC entfernt und im Array auf nil gesetzt. Was mich überrascht hat, dass Xojo keine eindeutige Referenz zur Runtime beim Erstellen eines dynamischen (Container)Controls anlegt.
Code siehe unten falls das jemand interessiert. Wahrscheinlich “Oldstyle”. Liegt an über 25 Jahren Programmiererfahrung mit diversen Sprachen (dBase, Clipper, C, Delphi, 4D, etwas XCode). Realbasic / Xojo erst seit etwa 2 Jahren.

Die Komponente links auf dem Bild ist FGSourceList (jetzt freeware).

Eine neue Seite im Pagepanel wird angelegt über:

  dim lOK as boolean = False
  dim cName as string = item.name
  dim nWin as integer = dWinDict.Lookup(cName, -1).IntegerValue
  dim nCC as integer = dCCDict.Lookup(cName, -1).IntegerValue
  if nWin > -1 then 
    KarteiPagePanel.Value = nWin
    return
  end if
  
    KarteiPagePanel.Append
    nWin = KarteiPagePanel.PanelCount -1
    
    dim cont as new ContSuchTable1
    cont.EmbedWithinPanel(KarteiPagePanel, nWin,0,0, KarteiPagePanel.Width, KarteiPagePanel.Height)
    cont.lblTitel.Text = cName
    cont.LockLeft = True
    cont.LockTop = True
    cont.LockBottom = True
    cont.LockRight = True
    cont.init(cName)
    cont.Visible = True
    lOK = True
    aContArr.append cont
    
    #if TargetMacOS then
      item.EjectButton = True
    #else
      item.ButtonImage = eject
      item.Button = True
      item.ButtonActive = True
    #endif

    dPPDict.Value(nWin) = cName
    dWinDict.Value(cName) = nWin
    dCCDict.Value(cName) = aContArr.ubound
    KarteiPagePanel.Value = nWin
    ChangeDropDownMenu(cName)

Gelöscht wird die Seite über:

  dim cName as string = item.name
  dim nWin as integer = dWinDict.Lookup(cNAme, -1).IntegerValue
  dim nCC as integer = dCCDict.Lookup(cNAme, -1).IntegerValue
  if nWin > -1 then
    KarteiPagePanel.Value = nWin
    if KarteiPagePanel.Value = nWin then KarteiPagePanel.Remove nWin
    dPPDict.Remove(nWin)
    dWinDict.Remove(cNAme)
    dCCDict.Remove(cNAme)
    if (nCC>-1) and (nCC >= aContArr.Ubound) then aContArr(nCC) = nil
    item.EjectButton = False
    return
  end if