Not showing a window when updating data on that window

In the app I’m building I have a main window that’s the primary end user interface. There is a second window, full screen, that only shows up if you select it from a menu, which gives you access to various administrative and setup tasks.

I use a bunch of computed properties to drive this application. A timer reads data from a hardware controller 10 times per second. The results populate computed properties. Some of these properties will update the administrative window’s various text fields, so you can see what the hardware values are.

Until today I had the timer turned off, as I was working on other stuff. Now, as soon as the registers are read by the timer, and the computed properties are populated, the administrative window pops to the front. I assume this is because text fields on that window are being updated when the computed properties are updated. But the AdminSetup window should remain out of sight until explicitly brought forward. I have about 20 properties that could trigger this behavior, and I’ve added the following test around all the calls that update the UI that I can find:

if wAdminSetup.Visible = true then
  //update the UI here
end if

However, it’s still popping up the wAdminSetup window. It may be that I missed some instances, but I’m wondering if there’s a better way to prevent this window from automatically appearing?

Shouldn’t the values update even if the window isn’t visible without forcing a change in its visibility? Any way to do that?

Or am I completely wrong about what’s going on here?

Updating a text control on a Window should not bring that window to the front. SetFocus could do it. Can you show some code that is doing the updating?

I’ve just put an example together. Window1 is just a blank window. Window2 has an EditField (called EditField1) and a timer (Timer1). Timer1’s action event fires once a second and has the following code:

TextField1.Text = Str( Val( TextField1.Text ) + 1 )

The Window2 counts up the value once a second and still works when it is in the background, without jumping to the front.

What does the code look like that updates your background window?

Just a moment. What is “wAdminSetup”, is it the window’s class name? If so then you are using implicit instance and that is causing the window to pop into view. Just referencing this Class Name will cause an instance of the window to be generated and shown, even if it hasn’t existed before. The instance is Implicitly created by accessing the class name.

Where is the timer. Surely it should be on the background window? Then if the window is closed the timer will not even run and you don’t need to check if the window is open.

I would strongly suggest you disable Implicit Instance (on the cog tab of each Window). This will prevent evil things like this from happening. If a window needs to access another window you should have a variable or property that holds a reference to the target window. Access is via this reference.

If there is only ever one wAdminSetup window then hold a reference to it on the App class. Create shared property, let’s say called AdminWindow. In any code in the application you can access it as follows:

if App.AdminWindow <> nil then
   // Do some stuff on the AdminWindow
end if

To show the wAdminSetup do this:

App.AdminWindow = New wAdminSetup

The window will now create and show. the code using the App.AdminWindow will now detect that it is open and work. When you close the wAdminSetup class do the following:

App.AdminWindow = Nil

Again, other part of the code can now detect that the window isn’t available.

Any code within the wAdminSetup window should just reference Self or have no name at all for the window, when referring to controls on their own window.

I’m not calling SetFocus. And I’m not positive what code is causing it. When I have the line in the timer that updates the computed properties commented out, the Admin Window doesn’t appear. So i’ve narrowed it down to those, I think.

wAdminWindow is just the name of the window. I prefix window names with “w,” buttons with “b,” text labels with an “l,” etc, so they can be easily differentiated and grouped in the navigator on the left side of the IDE. Otherwise everything is a mess. Because you can’t really organize that view in the IDE in a meaningful way when there are lots of controls on a window.

The timer is on the main window. It starts on the Window’s Opening event and runs in the background.

I’ll look at this tomorrow when I’m back in the office. wAdminSetup is where you set up configuration files that the main window uses - it accesses the same hardware as the main window, but only for the purpose of creating custom XML configuration files that the main window uses day to day. You don’t go in there often and I really don’t want to have to redo too much here to make it work. So I’m looking for the simplest fix.

I also have a floating status window that’s always open, and I could move all these updating fields into there, maybe behind a disclosure triangle, since you don’t really need this information when working in the main window most of the time.

You should look at what Jeff said, this certainly seems to target what you are seeing.

The default state for Windows you create using the IDE is implicit instance, at least it used to be (and I think it still is). If this is new to you (as it was to me many years ago), the rest of Jeff’s response maybe obscure because you do not really know what “implicit instance” means.
I suggest the following reads to get you familiar with it; and then maybe the rest of Jeff’s answer will sink in. If you already understand it then my apologies and ignore the rest.
Windows — Xojo documentation
implicit instance off - Getting Started - Xojo Programming Forum
Where is desktopWindow.implicitInstance - General - Xojo Programming Forum
Why implicit instance isnt your friend – Writings from the sticks (great-white-software.com)
I also thought there was a good Xojo blog on this topic but I did not find it via the good’ol google.

Thanks. I didn’t know about implicit instances with windows, but just read up on it this morning.

Thinking about the app more last night, however, I decided that the cleanest UI would be to move all of the data I’m updating to a normally-hidden part of the status window that’s always there (a floating window). When the AdminSetup window is open, the status window will expand automatically to show that information, since that’s the only time you’ll need to see any of that.

Who’s Jeff? My name is Ian :slight_smile:

2 Likes

Yes, that’s what I thought. That is what is causing all your issues. With implicit instance turned on and no window showing, just referencing the name will create a new window and show it. Even the following:

if wAdminSetup.Visible = true then

Will cause the window to show. even if Visible was false.

The simplest thing to do is to create a shared property on App that will hold the reference to wAdminSetup

Public shared MyAdminWindow as wAdminSetup

Change your tests from:

if wAdminSetup.visible = true then

// change to 

if App.MyAdminSetup <> nil then

When you want to open the wAdminSetup window, do the following:

App.MyAdminSetup = New wAdminSetup

When you want to close it do:

App.MyAdminSetup.Close
App.MyAdminSetup = Nil

Change all references to wAdminWindow to App.MyAdminWindow. Everything else can stay the same.


An implicit instance is one created implicitly, just by using the name of the window. If an instance does not exist it is automatically (implicitly) created. Its just like the devil, say his name and he will appear.

An explicit instance is one you create yourself:

var MyWindow as New wSetupWindow // this is explicit you are actually asking for the instance to be created.

MyWindow above is a reference to the instance of the Window. You can have more than one instance of the window open at the same time (I know that may not make sense in your application at this time). For example:

var MyWindow1 as New wSetupWindow
var MyWindow2 as New wSetupWindow

MyWindow1 holds a reference to one instance and MyWindow2 to another instance.

1 Like

My bad - not even close. Certainly meant Ian. - :person_facepalming:

brilliant

Mwahaha! I’m Jeff! :smiling_imp:

3 Likes

:smiley: I was talking about implicit instance. :smiling_imp:

i think if you use implicit instance, useing the classname,
you could set visible to false in inspector that it not pop up if it is created by first access, as example change a propertie there.

Somewhat. Every time you close it you need to consistently do that. Closing it will reset everything back to stock values and even the test to see if it is visible will cause it to reopen and come to the front (as a new window).

In all but the rarest of circumstances I would recommend against using implicit instance. For example, a tool pallet with no close button that is always going to stay around.

1 Like

Shared properties (class properties) does not fire implicit instances. I do control the status of ONE window using them.

E.g you can create a property as Shared isOpen As Boolean = False, and in the event Opening() → isOpen = True, and in the event Closing() → isOpen = False

You can consult myWindow.isOpen at any time without instantiating as side effect.

isOpen differs from (is) Visible. A window can be Open (in memory, working) but not visible, that’s another property, and belongs to the instance, not the class.

You may want also force some window being instantiated invisible… and then controlling the visibility afterwards. Just disable this:

1 Like

An alternative solution would be for the hardware timer to store the data in its own class. Any window that wanted to show the data could then have its own timer which pulled the latest values from where the hardware timer stored its data.

2 Likes

That would be better than one window updating another.