Viewing custom class properties at design time

I thought there was a way to make a property I have added to a custom subclass of canvas visible at design time so I can just assign that property a value while in the IDE. Either I’m mistaken about that, or can’t remember how to do it in Xojo 14r1.1. Can anyone help?

TIA

You can always search the forums. Searching for “custom class properties” brings up this.

https://forum.xojo.com/11705-custom-class-properties

Right click on the class and click Inspector Behavior. There you can do exactly as you remember.

1 Like

[quote=86992:@Roger Clary]I thought there was a way to make a property I have added to a custom subclass of canvas visible at design time so I can just assign that property a value while in the IDE. Either I’m mistaken about that, or can’t remember how to do it in Xojo 14r1.1. Can anyone help?

TIA[/quote]

  • Right click on the class and select “Inspector behavior”
  • Check the properties you wan to see in the IDE

Afterwards, when you drag this class over a window, the properties will show in the inspector.

Well, then I have a different problem. I had done the right-click on the class before posting here and my properties are not there. I see all of the properties inherited from the super (in this case: canvas) but I don’t see any of the properties I have added to my class. I have tried making those properties both protected and public, but no joy either way. Do I have to do something special to my properties to have them appear in the list exposed by right-clicking?

If your property is protected or private, it won’t show, but if it’s public it should be at the bottom of the list. Is there something different about your class? It’s super is Canvas, right? And it’s a regular property, not a shared property or something like that?

It’s a known bug. Goto your main Window1, then browse within a code region (ie event handler), then browse back to your window1 (or whatever you called it) and click the control/class instance. The custom properties should be available now. On a few occasions I’ve had to restart the Xojo IDE. The other bug is in “creating computed properties” On occasion converting a property will not prefix the name with an “m”, and the compiler will prompt an error that “…does not exist.” Simply pre-pend an “m” to the property that was created and named identically to the computed one. You’ll also notice another side effect of the last mentioned bug is that the non pre-pended property is created with Public scope and should be private.

Thanks, Bill. I thought I had made the props Public and tried it previously, but missed it I guess. Now that I made them public, they do show up.
Matthew: Maybe it was the fact that I saved the project after making them public that made it work. Thanks

I was under the impression (and observation bears this out) that only COMPUTED PROPERTY appeared in Inspector Behaviour?

Public properties (non-computed and computed) appear fine for me in Inspector Behavior. Tick the checkbox and then they are in design time as well.

What is the reason that you can only do this with public properties? After all, I have custom classes where I want to have different settings for each instance I add to the IDE …

Every instance you add to a layout will have separate values for these properties if you change the value for that instance. The inspector behaviour is a default initial value. You can only do this with public properties because, quite literally, the set up code a Window runs to create & initialize the properties can’t touch protected or private properties. There’s a method that creates & initializes all the controls which basically has code like:

Sub Window_CreateControls
    dim c as Control
   
    c = new <whatever kind of control>
    c.<property name here> = <value>
End Sub

You can’t touch a protected or private property in code like that. You can see this in your own code if you create a class that has protected or private properties:

Class Foo
             protected bar as integer
             private baz as string
End Class

Event App.Open
      dim f as new Foo

      f.bar = 120 // <<<< error !!!!!!!!
      f.baz = "hello world" // <<<<<<<<< error
End Event

Thanks Jason, but sorry, silly me, forgot some important info. Sometimes I know what I mean but write something different (which is a worry).

I have some custom classes where the properties are all private and are only accessed within the class, so they are nicely encapsulated . I would like to set the properties at design time so wanted to make them visible in the inspector, but I can only do that if I make them public. So It seems I have to choose between proper OOP encapsulation and convenience. But why?

[quote=425839:@Markus Winter]Thanks Jason, but sorry, silly me, forgot some important info. Sometimes I know what I mean but write something different (which is a worry).

I have some custom classes where the properties are all private and are only accessed within the class, so they are nicely encapsulated . I would like to set the properties at design time so wanted to make them visible in the inspector, but I can only do that if I make them public. So It seems I have to choose between proper OOP encapsulation and convenience. But why?[/quote]

:slight_smile: It happens to all of us…

if they are private then nothing outside the class itself can alter them so changing it on a per instance basis isn’t even possible (since the set up code would have to bypass private and reach inside and set the value).

There’s no way to make this work:

Class Foo
             protected bar as integer
             private baz as string
End Class

Event App.Open
      dim f as new Foo

      f.bar = 120 // <<<< error !!!!!!!!
      f.baz = "hello world" // <<<<<<<<< error
End Event

Controls are basically set up the same way and so only publicly exposed items can be altered (by you or us).

[quote=425841:@Jason Parsley]if they are private then nothing outside the class itself can alter them so changing it on a per instance basis isn’t even possible (since the set up code would have to bypass private and reach inside and set the value).

There’s no way to make this work:

Class Foo
             protected bar as integer
             private baz as string
End Class

Event App.Open
      dim f as new Foo

      f.bar = 120 // <<<< error !!!!!!!!
      f.baz = "hello world" // <<<<<<<<< error
End Event

Controls are basically set up the same way and so only publicly exposed items can be altered (by you or us).[/quote]

That’s what still puzzles me. I’m not trying to set it in app.open but in the IDE after I dropped an instance into my layout, so shouldn’t the compiler be able to set them as it does with any private or protected property? Private and protected properties aren’t shared class properties after all (though I’m no OOP expert), and the property can be changed within the class and different instances can have different values.

The compiler is respecting the scoping of the property. Setting properties with the inspector is not from within the class, so with regard to scope it’s equivalent to setting the properties in the Open event.

#@&$#! Can’t Xojo move the effing delete button away from the edit button!!! I keep deleting replies by accidentwhen I try to fix spelling mistakes!

Here again:

As far as I’m aware (basically I have no clue) the compiler reserves space for the instance variable, instantiates it, and sets its default properties. Then the constructor is executed, then open, both of which let you change those properties.

So why can’t you set a private property of an instance in the IDE. For example if you have a private Boolean property IsDone with default False then that could be set in the IDE and result in code IsDone = False being executed at the start of the constructor. If IsDone is set again later in the Constructor that is no problem.

So being privat (good OOP) and being settable in the IDE (convenient) are not mutually exclusive.

If the compiler isn’t doing it, then the IDE certainly could.

Or am I wrong about this?

Yes, you are wrong about it. :slight_smile:

When you “set” the property in the IDE the IDE keeps track of the values you want for that instance. Eventually, when you compile the IDE writes out code to make that layout the way you’ve set it up.
That code is then compiled and obeys the same scope rules as you have to. There’s no magic there. What you do visually in the layout editor the IDE turns into code.
If the properties you’ve set are PROTECTED or PRIVATE then the code the IDE would have to write would not compile at all (see my previous posts about what code the IDE generates looks like).

Hence the only properties you can set this way must be public.

[quote=425876:@Jason Parsley]Yes, you are wrong about it. :slight_smile:

… see my previous posts about what code the IDE generates looks like.[/quote]

But you put that code into app.open, so of course it won’t work there - but what if code for private instance properties is put into the constructor for that instance? After all we CAN put code in there ourselves, so the IDE should certainly be able to do it too.

I do understand that what you are saying is how the Xojo IDE works NOW - I just don’t see yet why it couldn’t work differently, thereby allowing private and protected instance properties to be set in the IDE.

To me it seems like an unnecessary limitation.

The code I posted previously and put in app.open is nearly identical to the code the IDE would generate to construct a window you design with very minor differences. But stylistically it is identical. That is very much what the IDE generates. So if that code won’t work then the code the IDE generates won’t work either for the exact same reasons.

Secondly, the code in the constructor is in the CLASS - not the INSTANCE. Every instance would run the exact same constructor. So if we put code in the constructor it would be the same for every instance and so every instance would have the same values.

“Ah” you say “but what if you called a constructor with ‘the right parameters’ so the control is set up once with those unique values for that instance?”

Exactly how would the IDE know which constructor to call if there are several?
They could all be similar, or worse have optional params so we’d have to somehow determine which of several possibilities is “right”.

How then does the IDE know what code to write for calling this constructor?
And it has to know this perfectly for every possible set up?
“Introspection!” you say

Except that when the IDE is running introspection doesn’t work on “data”. That’s really what the IDE has - data about what you want it to eventually compile - not runtime instances so that won’t work. We could only introspect the IDE itself - not the controls & classes you’ve created. They’re not running.

“Ah” you say “since the IDE knows the signature of the constructors you could know by parsing the constructor signature”
Not really
If you can tell me which property value matches which parameter when a person writes a constructor like:

Class MakeAMess
Inherits Listbox
Constructor( foo as integer, bar as integer, baz as integer)
End Constructor

property i as integer
property j as integer
property k as integer

and you expose i,j,k in the inspector
whats the right call to the constructor?

new MakeAMess(i,j,k) ?
new MakeAMess(j,i,k) ?
new MakeAMess(i,k,j) ?

There isn’t a way to do what you’re suggesting. Not accurately every time for any control a user or plugin author might write.