LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Dynamically adding controls of dynamic type

Hi all,

 

I know this is not natively possible at runtime, but I'm wondering what best practice is.I've read many similar posts, and the difference between theirs and mine is that it seems like most people want a dynamic number of controls of the *same* type, where I want different types.

 

My goal is to have one VI that we reuse for input validation of across several stages of user input. Same background, window size, and behavior. The intended behavior is to guide the user through inputting each parameter, greying out the next one until they fill in the current one with a valid value.

 

Here's a mockup of one screen:

 

ijustlovemath_0-1584637044619.png

 

As you can see, it's got several base data types: Rings, Strings, and Doubles. Each associated data type will have a static validation VI, the prompt text to be displayed on the left, and the type of the control itself (probably using the OpenG enums for cluster type).

 

All that being said, here's my current implementation plan:

 

1. Fix the maximum number of controls for the screen, at say, 6.

2. Instantiate 6 controls of each type, eg 6 strings, 6 rings, 6 doubles

3. Place arrays of references to these controls into a dictionary, which maps Type Enum -> Array of references

4. Take an input array of (Prompt Text, Validation VI, Control Type, Array of Possible Values (as string))

5. Loop through the input array, formatting each of the controls as appropriate (eg location, width, height etc)

6. When the value of any control changes, re-run all validation VIs on all the corresponding controls (using a dictionary mapping

7. Show a greyed out 'Next' button that only changes to clickable when all validations pass.

 

Is there a nicer way to do this?

0 Kudos
Message 1 of 8
(3,292 Views)

If you will be traversing multiple UI screens of the same basic layout, but varying data types depending on which is the active UI screen, why not treat all inputs as strings and validate the data accordingly as it has been input. You can have dynamic dispatch methods that validate the data elements and internally can convert the data to the specific data types. Keeping a single UI style sheet and letting the business logic portion of your code worry about the correct data types will simplify things. This is an OOP approach but it should be very flexible.

 

You can have a base class which a data element. You UI would pass a data element instance to your various component classes. Internally, the object can be cast to the appropriate data type and you can have child classes with appropriate accessor types. The UI would only need to deal with strings. The base class would have an abstract method "validate" that the child classes implements. The data type specific read/write accessors would not be dynamic dispatch but that is fine. The objects/components dealing with specific data would know the appropriate type and can cast the data element object to the correct child instance and then your accessors at that level do not need to be dynamic dispatch.



Mark Yedinak
Certified LabVIEW Architect
LabVIEW Champion

"Does anyone know where the love of God goes when the waves turn the minutes to hours?"
Wreck of the Edmund Fitzgerald - Gordon Lightfoot
Message 2 of 8
(3,274 Views)

I think that sounds like a good design as a software engineer, my main concern is the confusion the users would have in being "allowed" to enter arbitrary text in the field, only to have it correct them. I like that the basic data types do this kind of enforcement automatically, and haven't yet found a nice way to do this with my own string data types. I know there's the "update string value while typing" option, which allows this to be done, although I'm a little unclear on how it's done in a nice way. Although, again, perhaps I'm missing some best practice here.

 

Another issue with the basic controls that I'm also grappling with is that most of them don't update until you click away/hit enter, which is counterintuitive to most users, and is hard to enforce on my end (without convoluted checkbox UIs which I'd rather not use). Any advice on that?

0 Kudos
Message 3 of 8
(3,268 Views)

By "do this kind of enforcement automatically", I mean that typing the letter 'r' into a double control results in nothing happening, which is a pretty clear "you can't do that" message to the user.

0 Kudos
Message 4 of 8
(3,265 Views)

Also, in case it wasn't clear, some of these controls are drop-down menus while some are text fields, so while you can do all of that with a combo box, I'm a little unclear right now how to, for example hide the 'check mark' on the right side of the purely string inputs.

0 Kudos
Message 5 of 8
(3,260 Views)

I think your method would work, but it would probably be easier to use six clusters (where each contains one string, one double, one ring control, etc) and just show or hide each one as needed. Call them "item 1", "item 2" etc and build the references into an array. (Note that you can't just make it an array of clusters, as each element in the array has the same set of properties- I don't think you can show one control in just one array element. Could be wrong though, I haven't tried in a while.)

Message 6 of 8
(3,202 Views)

I like the idea of cluster-ifying it, that would make it very straightforward! I'm currently almost done implementing the original post, will see what kind of changes I need then.

0 Kudos
Message 7 of 8
(3,198 Views)

By the way, this would be a great case for encapsulation in a QControl. You could make one cluster that wraps all 6 of the sub-clusters (to boil it down to a single reference) then have methods that modify the controls within it. All of your GUI logic would then be contained in a nice reusable package, and your "business logic" could be much clearer.

 

If it were me, I'd make a generic "6-question cluster" QControl as an abstract, then make a concrete implementation for a given set of questions. The abstract would handle the low-level show/hide/gray-out/etc of the individual text boxes, and the concrete would provide the correct labels and processing of the individual entries.

 

I used a similar method to make a datagrid Qcontrol and it's been great. (There's already a datagrid Qcontrol as an example, but it didn't quite work the way I needed it to so I made my own.)

0 Kudos
Message 8 of 8
(3,155 Views)