What is the best way to share parameter values across views?

Hi
I have tried a number of ways to pass values from one view to another. One method that seems to have promise was to have a global dictionary as suggested by Michel, but I couldn’t get it to work.
I managed to get it working by putting code into the Activate method of the window I wanted to pass data into from the calling window.

I would appreciate advice as to how to do this in an optimal way.

Michel Bujardet

Testers

Mar 2016

No need to shadow all properties. There is another way that allows to keep views around and access their properties at any time from wherever :

  • Create a global dictionary in a module. I called it Dico
  • In app, put

Dico = New Dictionary

  • In View 1 Deactivate, so the view is saved before pushing another one :

dico.Value(“View1”) = self

I added a label to View1

I then added a button to pushto a View 2 that contains two buttons :

Sub Action() View1(Dico.Value(“View1”)).Label1.Text = “Pickaboo” End Sub

Sub Action() self.close End Sub

So one button modifies the content of Label1.Text on View1 from View2, the second one closes View2.

When View1 reappears, the label has been modified.

Note that with this technique you no longer need to create a new view when you want to display again a view that already exists. For instance :

if Dico.HasKey(“View2”) then PushTo(View2(Dico.Value(“View2”))) else Dim newView As New View2 Self.PushTo(newView) end if

Ive done similar things to Michel but in a simpler form
At the App level, I give it values

dim theViewTypeA as ViewA
dim theViewTypeB as ViewB

When each view is needed, the code is

if app.theViewTypeA = nil then app.theViewTypeA = new ViewA
//then push it

Values of these can be read at any time.
OR
You can simply create a global module, with global values ,and use those anywhere you want.
It’s ‘frowned upon’, but every time anyone has tried to demonstrate another way to do global variables, they end up with a complicated method of a big class or dictionary.
That is exactly the same thing but with a fancy hat. Sue me. :slight_smile:
Global variables held in a view or window is silly, though.
Keep em all in one place.

Hi JeffT,
I really like the idea you suggested, but I keep getting the compiler complaining to me and can’t implement it. I must be doing something really dumb or not understanding your thought processes, Is it possible to provide a bit more detail, or even a short working example?
Thanks in advance for any advice bio feel able to share.
regards,
Phil

Add a module
Call it glob

Add a property to it.
If one of your views is called Optionsview, then the property is

TheOneAndOnlyOptionsView as OptionsView

make sure the scope is Global

In App.open do this:

TheOneAndOnlyOptionsView = new OptionsView

Later, you can push that into view by referring to TheOneAndOnlyOptionsView
You can access variables and controls on that view by using dot notation

TheOneAndOnlyOptionsView.someproperty = 6

and any other part of your code including other views can do that

Thank you for your quick response.
I tried that but messed it up somehow.
Now I can call the TheOneAndOnlyOptionsView.
I got everything working except that when I try to change the property of a textfield
TheOneAndOnlyOptionsView.TextField1.text = “Hi there”
I get two errors:
“This method is protected and can only be called from within its class”
and
Type “Int32” has no member named “text”
I think your solution is exactly what I am looking for, and is very elegant, but
I am wondering what I am doing wrong.
Any suggestions?
Thanks again for your help

Offhand,I cant recall if there is a need to make the controls themselves public.

One way to do it is to add a public method to the view

'DoStuff (s as string)

In that ,
TextField1.text = s

Elsewhere
call TheOneAndOnlyOptionsView.DoStuff "New Words for textfield"

It works fine when I go to change the text on a secondary screen from the first one seen, but doesn’t seem to work when I want to pass information back to the main screen (first one opened). I have tried both the simple method
TheOneAndOnlyOptionsView.textField1 = “stuff” and using a function, as you suggested. TextField1 has global scope.

The debug log includes these lines:

Feb 23 04:15:23 Philips-MacBook-Pro-2 syslogd[9423]: ASL Sender Statistics
Feb 23 04:15:24 Philips-MacBook-Pro-2                 com.apple.CoreSimulator.SimDevice. 56B3CC5C-E7CD-4D47-B4BB-C71998D00266[9421] (com.apple.AssetCacheLocatorService): Unknown key for Boolean: EnableTransactions

Feb 23 04:15:24 Philips-MacBook-Pro-2 com.apple.CoreSimulator.SimDevice.56B3CC5C-E7CD-4D47-B4BB-C71998D00266[9421] (com.apple.AssetCacheLocatorService): Unknown key for Boolean: EnablePressuredExit

These error messages dont seem to have any bearing on what you describe.

Then don’t “pass back to the screen”. I know the principle works, but I dont know what your code looks like.

Why not just keep variables in the global module, and set them instead?
Have all your views refer to the global module.
When a view is activated, take any information you need for a control from the global variable.

I get it.

The only problem is that on going back to the very first screen that is shown, it does not seem to refresh the information that is displayed. Unless code is entered into the ‘Activated’ event handler (for mobileScreen as the parent, and ‘Activate’ for iOSView)
Then I can get the field I want to hold the data from the secondary screen to show the change on returning to the first screen. If I put the code in the calling button (for example) after the call is made to the secondary screen, it sometimes works but doesn’t seem to be reliable.

I have finally figured it out. (with thanks to Byron for pointing the way). It is a bit different in iOS cf. desktop

If the first window is called winMain and the secondary window is called winSub, add a property to winSub called ‘callBack’ with type of winMain.
When calling the subsidiary window from winMain, do so like:

Dim w As New winSub
w.callBack = Self
Self.PushTo(w)

To pass a value back to the calling window from within the subsidiary window (winSub), do something like:

callback.textFieldInMainWindow.text = “something to crow about!”

The property callBack refers to the main window.

I have to admit I had just skimmed this before

That you wrote will work
One thing you might consider is putting a constructor on winSub

Class WinSub
    private property callBack as WinMain

    Sub Constructor(whatToCallBack  as winMain)
        callBack = whatToCallBack
   End Sub
End Class

Then your code is

Dim w As New winSub(self)
Self.PushTo(w)

There are other things that can be done to make this more flexible

HAve you tried B4i?, what you want to do is really easy there:

Thanks npalardy,
Now that is really neat!

“There are other things that can be done to make this more flexible”

Would you care to elaborate?

No,
I am coding using OSX. I do have parallels and VMware running on my laptop, with windoze as a virtual environment, but still not too happy with it.
When I me to Android development, I will take another look. Thanks for the reminder.

well if you defined an interface with many methods and each view implemented it then you could mix and match who called what

as it is not only a WinMain can open and set itself up as the callbackl