Dynamic container control reference

Hello guys,

I`m struggling with this for a few days and any idea or advice is more than welcomed .

i`ve created 2 container controls which are 2 list boxes with some buttons and fields.

The workflow is like this for the moment :

masterContainercontrol

searchContainer.

in the master control i have a button where i set the second container controls as (dim SearchPopup As New SearchContainer) then i populate the listbox within the new declared container and all works perfect.

i add the container control on the window and it will be ccm1(Super : masterContainercontrol)

on the ccm1 i have another listbox where i have to paste the selected data in the SearchPopup, but because it is different control all the time on both parts i cannot control or i cannot get the control on which is which. so i cannot use this code :

[code] dim wordIdx, wordCount as integer

wordCount = lbSearch.listCount - 1

dim name as string

for wordIdx = wordCount downTo 0
if lbSearch.selected(wordIdx) then

  lbATCD.AddRow(lbSearch.Cell(wordIdx,0))
  
end if

next
[/code]

now, how i can reference the container controls in the new defined controls in the window so they can interact to each other ?

the idea is to have like a master listbox with a popup in which i have a search field and a listbox which is dynamically populated according to the input from the search field, more like a filter, then the user selects the multiple fields and once mouse Exit is triggered then the records should be transferred into the master list and popup should close.

I could avoid using the container control but the problem is that i have around 80 controls based on this container control and to create this control that many times i go crazy and then does not use DRY anymore so bad coding, just trying to simplify the usage of the design.

Thanks a lot in advance, im simply out of ideas and im sure that it is just a simple thing .

Instead of

Dim SearchPopup as new SearchContainer

, you can add a property SearchPopup to your window and do :

SearchPopup = New SearchContainer

Then you keep a reference.

You can do the same with an array if you have many instances.

I also have used a Dictionary when there are really many instances. I find that conve,ient to be able to call the value by the name.

[code] Dim SearchPopup as new SearchContainer

Dico.value(“SearchPopup”) = SearchPopup

SearchPopup.EmbedWithin(self, 0, 0)[/code]

ContainerControl(Dico.Value("SearchPopup")).close

Hello Michel, well my issue is not the SearchPopup itself, i was thinking to that part as well actually i was playing with that now, my issue is how i transfer the data to the mastercontainer so far what i did to reference the data between them , in the master container button i put something like SearchPopup.SearchDict = Self.SearchDict, and so far it works in a way , maybe wrong but it works. so i`m getting the dictionary from the main controller and use it in the search popup to filter the data , the idea is to populate the searchpopup with the date from the db removing the data that already exists in that dictionary that gives the unicity of the records so that they are not added 2 times.

Until now what i achieved was to load the master control, populate the list in the popup list and show the popup, but once i did that i have no idea how to put selected list into the master when i dont know the master name as a reference and i cannot call any method lets say to save the data or something like that , its like there is a link between master -> popup but nothing in reverse, between the popup and the master , and like both are referenced dynamically so that i can use different data in them its kind of hard or at least for me .

Thanks again.

And to put a property in one window i have then dynamically loaded between 5 and 25 so that means to have 25 properties plus 8 more on the master 33 properties, and then maybe to find a way to catch the mouse exit event on the list to trigger a method on the desired master container to save the data or something like this, but still no idea how.

Sorry, I do not get the notion of “master control”. Are you talking about the master class ?

Here is a demo project of what i`m trying to achieve.

So basically all will be like the 4 controls on the left side , the right controls are just for seeing the popup position.

So, on window opening all the date gets loaded into the main container controls (list1 to list4) then once you press on the blue button you should get a popup listbox with a search field, the list in that popup gets loaded from a table in the database and on loading (the LoadList in the vdSearch) it checks if in the dictionary (SearchDict where the data from the main list exists) if data exists does not add it to the search list.

The idea is to select one or more records from the popup and on mouse exit to drop them in the master list and as well into the dictionary and to close the popup.

so far this part does not work or i don`t know how to link it.

Im sure that im doing it wrong but i have no idea how to link them.

There is a lot of garbage there, like unused properties and methods but the project works on run.

Thanks again.

Hi Aurelian,

i did a quick look into the Demo…

in vdListBox
bbDropList.Action you write:
dim SearchPopup As New vdSearch

This creates a new Object only in the scope of the Action method:
instead do this:

If SearchPopup1=nil then
SearchPopup1 = New vdSearch
else
end if

You have already defined SearchPopup1 in the container Control as an Property.

Then you can reference to SearchPopup1 for the Lifetime of vdListBox

Greetings Björn

Perhaps you can also think about your plan of putting the main stuff of populating the “master control” with the multi selection of the listbox selections in vdSearch.

When the User moves the mouse out of the range of the vdSearch the Populate Process will immediately start. Think about Drag and Drop of the to a place you specify.

Hello, well indeed but i need the other way around , the decisive control will be that Searchpopup.MouseExit event, that will put the data into the main listbox and close itself, that is my big issue, and actually i just need the popup to be active only when it is visible, once closed no need anymore as it will be initiated again on button push

i forgot to add a line in the code , in the wmain -> lbRecords -> Change you have to put the line after else :

mCurrentRecordID = me.RowTag(Me.ListIndex)

in order to populate each listbox and update it dynamically on record change

[quote=252142:@Björn Dohle]Perhaps you can also think about your plan of putting the main stuff of populating the “master control” with the multi selection of the listbox selections in vdSearch.

When the User moves the mouse out of the range of the vdSearch the Populate Process will immediately start. Think about Drag and Drop of the to a place you specify.[/quote]

Well i think to that as well but the users wanted that way , that is the purpose of the popup.

So for me to understand what you want to do…

the vdSearch “lives” only when it is visible? and can be used by different vdListBox and its scope is the window? This vdListBox (is this your master control?) will be populated after after selecting multiple rows?

If so, don’t use SearchPopup1 in vdListBox. Delete this Property in vdListBox and recreate it in the window itself. Also creat a new property in vdSearch “mastervdListBox”

bbDropList.Action:
Self.SearchPopup1 As New vdSearch
SearchPopop.mastervdListBox=//reference to your MasterContainerControl

Hope this helps…

[quote=252148:@Björn Dohle]So for me to understand what you want to do…

the vdSearch “lives” only when it is visible? and can be used by different vdListBox and its scope is the window? This vdListBox (is this your master control?) will be populated after after selecting multiple rows?

If so, don’t use SearchPopup1 in vdListBox. Delete this Property in vdListBox and recreate it in the window itself. Also creat a new property in vdSearch “mastervdListBox”

bbDropList.Action:
Self.SearchPopup1 As New vdSearch
SearchPopop.mastervdListBox=//reference to your MasterContainerControl

Hope this helps…[/quote]
Well i tried this way , See the link so far it works but it seems that it is crashing , and i don`t know why .

so to get the point of the whole setup :

  1. On window open the main listbox populates and then it will select record 0 so the first row, that triggers the 4 lists to get populated
    2 the user presses on the button this search list shows, the reduce the list by the search field(not yet implemented) or they multiple select the rows and then once they either do how i just did , drag and drop the rows to the other list or on mouse exit the records get updated on the master one, then the SearchDict gets updated and then the search list (the popup) disappears and not needed anymore until the user presses the button again. in total i have around 80 controls like that so i need to make it as neat as possible to be able to reuse it always and easy .

Hope that you got my point.

Thanks again for help.

It crashes in LoadList of vdSearch with NilObjectException because there is no reference to the dynamically loaded/created ContainerControl or it is not loaded…

here the error occurs:
lbSearch.DeleteAllRows

so you can check:
if self.truewindow.myvdserachproperty = nil then
// nothing happens or you create a new one of vdSearch
self.truewindow.myvdserachproperty = new vdSearch
else
self.truewindow.myvdserachproperty.lbSearch.DeleteAllRows
//do whatever you want
end if

i don’t see a property for the vdSearch in your Window where you can reference to. It’s important that you understand that objects only exist where you define them.

you call the LoadList method from somewhere else in your code but there is no object defined at this moment i think. You first have to reference to this defined object. For this you have to create property myvdserachproperty in wmain

Well indeed, the idea was not to have to many so maybe instead of 80 properties referencing 80 container controls i should put a dictionary .

As for the drag and drop it works ok but they don`t like it , to much clicks, to have that, so back to the original idea, Select the records and on mouse exit it should copy them into the main listbox and then close the popup.

Thanks again i`ll look more further into this issue.

You don’t need to create 80 properties :slight_smile: if you declare the property as an array on time in the window

mymaincontaincontrol() as vdListBox

somewhere in the code (window.open?) you create your array of container controls like this:

dim mytempcontainercontrol as vdListBox
mytempcontainercontrol = new vdListBox
mymaincontaincontrol.append(mytempcontainercontrol)

Dictionary vs.Array

choose Array if you need to iterate through all the members of the array

choose Dictionary if you specify the member by a key Value

i think if you you want to setup all the dynamically loaded Containers an array is the preferred way…

one more word about referencing to other objects or code from dynamically loaded ContainerControls:

if you want to reuse these containers in different windows you have to typecast the window type

for example accessing the array or dictionary of the window in wmain:

dim mywindow as window
mywindow = self.truewindow

//Typecast here

if mywindow isa wmain then
wmain(mywindow).myarray/mydictionary //then you can access the properties (array or dictionary) and methods here….

this is special with dynamically loaded ContainerControls. But they are very powerful

hope this helps :slight_smile:

another idea for your mouse exit:

http://documentation.xojo.com/index.php/ListBox.Selected

store the values of the listbox in an array property in main or the vdListBox Container Control after each selection in listbox. then this array lives on when vdSearch closes because of mouse exit. On mouse exit populate the main container control with the array of strings you have just selected.

this should work

[quote=252204:@Björn Dohle]one more word about referencing to other objects or code from dynamically loaded ContainerControls:

if you want to reuse these containers in different windows you have to typecast the window type

for example accessing the array or dictionary of the window in wmain:

dim mywindow as window
mywindow = self.truewindow

//Typecast here

if mywindow isa wmain then
wmain(mywindow).myarray/mydictionary //then you can access the properties (array or dictionary) and methods here….

this is special with dynamically loaded ContainerControls. But they are very powerful

hope this helps :-)[/quote]

Thanks but now im more and more confuse, im more the example learning guy so if i see the code running i understand the logic, otherwise its hard for me to follow, and i still dont see how i can reference the popup in the listbox and how should i know which to call and when, i guess i have to read more about this , unfortunately there is no sample or demo on the xojo docs to help me .

Thanks again for all the support. i`ll have to clean the demo project and look into it how to make it work.

the main idea is like a main window, and then container controls as sub windows, something like tab panels so my container controls are general and will have to be referenced in multiple container controls something like 3 so i guess the property should be inside the master main window and then looked up in each window. i`ll try to do so and maybe i get it as a functional project eventually.