Calling on Custom Class Arrays - Problem

Using REAL Studio 2012

Hello, everyone. I have created a custom class (no super) to hold several variables and single-dimension arrays. I have a global property to hold the Custom Class array (e.g. MyClass() as CustomClass). I can successfully append new classes to the array, and then work with the variables and single-dimension property arrays. As an example:

[code] Dim DataClass as new DataClass

DataClass = New DataClass
MarkerClass.Append DataClass
MarkerClass(0).Colour= RGB(255,0,0)

DataClass = New DataClass
MarkerClass.Append DataClass
MarkerClass(1).Colour= RGB(255,0,0)

Then from another window, or the same, or within App…
Dim c as Color
c = MarkerClass(1).Colour
etc.
[/code]

My issue is I can call on this data and work with it just fine… depending on where I call on it from within my project. If I try to call upon my custom class array within a Canvas.Paint it results in an Out of Bounds exception, but if I try to call upon it within the Canvas.MouseDown it works. From checking the UBound of the class array between the two, the MouseDown event recognizes what has been appended to the array, but the Paint event thinks the array is empty (-1). I have tried playing with it, using simple code such as above, and I don’t seem to have much luck. From some googling and my debugging, I fear this is leaning more towards a bug (it would seem control arrays don’t behave as arrays and have been renamed in Xojo as such)? In short, with the simplest execution of code, aiming to only grab a variable of my custom class array, the result varies from working to returning an Out of Bounds exception depending on where I call from.

Any ideas? Cheers!

My thought: You are calling Dim MarkerClass() As DataClass somewhere in your code, either when you are appending it or in Paint. Wherever it is, it is creating a new, local variable that happens to have the same name as your property. When you append to it, or when you try to access an element, depending on where this unneeded Dim is, you are using the local variable that vanishes as soon as the method has completed.

BTW, did you know that this would work?

dc = new DataClass
MarkerClass.Append dc
dc.Colour = RGB( 255, 0, 0 )

dc = new DataClass
MarkerClass.Append dc
dc.Colour = RGB( 255, 0, 0 )

Hover the mouse over “MarkerClass” in both the Paint and Mousedown and note the difference in location.

I’m thinking the paint event is firing before the code to populate the array has run.
Try something like

if MarkerClass.ubound=-1 then return break
in your paint event. See if it gets to the break line after resizing the window or something to cause a refresh.

[quote=87235:@Kem Tekinay]My thought: You are calling Dim MarkerClass() As DataClass somewhere in your code, either when you are appending it or in Paint. Wherever it is, it is creating a new, local variable that happens to have the same name as your property. When you append to it, or when you try to access an element, depending on where this unneeded Dim is, you are using the local variable that vanishes as soon as the method has completed.

BTW, did you know that this would work?

dc = new DataClass
MarkerClass.Append dc
dc.Colour = RGB( 255, 0, 0 )

dc = new DataClass
MarkerClass.Append dc
dc.Colour = RGB( 255, 0, 0 )
[/code][/quote]
Hello and thank you for your input. I think you are correct in that essentially MarkerClass() is being reDimmed, hence why it varies between holding my original appended data and being empty depending on the call location. I'm puzzled though because at this point I have made a blank project with the following setup:

[code]MarkerClass() as DataClass as a public property in the App (I need to be able to call on it and change it from throughout the Application)

Sorry, I did not mean to submit that yet and I cannot find the edit button, on a roll here!

I have a new blank project which consists of:

MarkerClass() as DataClass as a public property in the App

The following code in the App.Open event:

MarkerClass.Append new DataClass MarkerClass(0).Name = "Testing" MsgBox(MarkerClass(0).Name)
This code returns “Testing”.

If I then run the code within a blank Window1.MouseDown event:

MsgBox(App.MarkerClass(0).Name)

It returns “Testing”.

If I then try to put the same code inside a Canvas.Paint event, with a an If… Then statement to avoid it firing until I have set a boolean to proceed it returns an OutOfBounds exception, UBound returns -1 for App.MarkerClass, and it seems to be wiped.

[code]PushButton.Action making TestPaint (Boolean) = True and Canvas1.Refresh

Canvas.Paint code:
If TestPaint = True Then
MsgBox(App.MarkerClass(0).Name)
End If
[/code]
When the pushbutton is pressed, the code in the Canvas.Paint fires, and returns OutOfBounds. I have tried this with all sorts of stuff, different classes, different ObjectEvents, I have tried moving the MarkerClass() as DataClass to be native to Window1 etc. and I still cannot fix it.

Cheers everyone so far. To Tim, thanks, a good call. I checked and all of the call instances for MarkerClass call back to the public App property.

The code in App.Open should run before anything else so your array must have been made when Canvas1.Paint fires. Are you sure nothing tampers with MarkerClass() when the boolean is set for it to proceed?

Try adding a break to your code…

If TestPaint = True Then break MsgBox(App.MarkerClass(0).Name) End If
When the debugger comes up click on Globals > App > MarkerClass and see how many elements are there. If it’s -1 then somethings resized it or it’s been reassigned to a new array. You’ll need to add more breakpoints and check the array in more places or post the project somewhere.

Also, if you show a Msgbox from Paint, closing the msg may trigger another Paint which shows another Msgbox, etc. System.DebugLog is one way around this.

I duplicated your setup as you described it and I don’t get an error. MarkerClass is sized correctly in canvas.paint. I even manipulated the properties of the implicit instance Window1 in app.Open and it still didn’t error out. The only way I could get it to error was if I called Window1.Show or Window1.Visible=true in app.Open before I appended to MarkerClass. Then I got an error.