DaveKielpinski Posted October 11, 2007 Report Share Posted October 11, 2007 Dear all, I am trying to use a dynamic event inside the Facade of an XControl. The event registration seems to produce a refnum, but the event case doesn't execute when the event occurs. I don't have much experience with dynamic events, but I read Ton's nugget on the topic. Is this a difficulty with XControls in particular, or am I just doing the event wrong? Thanks in advance, Dave Quote Link to comment
Michael Aivaliotis Posted October 11, 2007 Report Share Posted October 11, 2007 I don't know what the "NI recommended way" is because they don't have any documentation on this, but here is how I'm doing it and it works: Quote Link to comment
Ton Plomp Posted October 11, 2007 Report Share Posted October 11, 2007 QUOTE(Michael_Aivaliotis @ Oct 10 2007, 07:46 PM) I don't know what the "NI recommended way" is because they don't have any documentation on this, but here is how I'm doing it and it works: In the http://forums.lavag.org/downloads-file104.html' target="_blank">Boolean XControl I do it with the Init and Uninit abilities. Ton Quote Link to comment
DaveKielpinski Posted October 12, 2007 Author Report Share Posted October 12, 2007 Thanks for your helpful comments! Michael, sorry if I'm being stupid, but I don't see where the dynamic event shows up in your code. I only see the event registration part. I tried adding a case to the event structure of the Facade to handle the event, but still nothing happens. Also, don't I have to unregister the event somewhere in the code? Ton, I did look at your code, but I need to allow user operations to trigger event registration... I think this wouldn't be possible using the Init ability? Best,Dave ps. The whole point here is that I am trying to implement the hack described by Norm Kirchner in post #5 of http://forums.lavag.org/Events-from-an-arr...ters-t8825.html. The FP of the Facade is an array of clusters, and when a user clicks on a cluster, I need to get the refnum for the cluster rather than the refnum for the whole array. Quote Link to comment
Ton Plomp Posted October 12, 2007 Report Share Posted October 12, 2007 QUOTE(DaveKielpinski @ Oct 11 2007, 10:32 AM) Thanks for your helpful comments!Ton, I did look at your code, but I need to allow user operations to trigger event registration... I think this wouldn't be possible using the Init ability? You can use the Init ability, only make sure you use a dummy registration (as I showed in my Nugget and NI in their example) in the Init. If there's the need for the event registration write the correct control reference to the event registration (if I'm right that's exactly what I did in the Boolean XControl). Ton Quote Link to comment
Michael Aivaliotis Posted October 12, 2007 Report Share Posted October 12, 2007 QUOTE(DaveKielpinski @ Oct 11 2007, 01:32 AM) ... I only see the event registration part. Do you then add a case to the event structure of the Facade to handle the event? Yes, I didn't show that case. You need to add it. QUOTE(DaveKielpinski @ Oct 11 2007, 01:32 AM) Also, don't I have to unregister the event somewhere in the code? I forgot - You could put that in the Execution State Changed Event. Run mode false case. Quote Link to comment
Michael Aivaliotis Posted October 12, 2007 Report Share Posted October 12, 2007 QUOTE(tcplomp @ Oct 11 2007, 01:46 AM) You can use the Init ability, only make sure you use a dummy registration (as I showed in my Nugget and NI in their example) in the Init.If there's the need for the event registration write the correct control reference to the event registration (if I'm right that's exactly what I did in the Boolean XControl). Ton yes, this should work if you use a null ctrl refnum constant. Quote Link to comment
DaveKielpinski Posted October 12, 2007 Author Report Share Posted October 12, 2007 I did add another event case to the Facade as Michael suggested, with just a indicator to flag whether the event fired. Still the event never seems to fire! I double-checked my code against Michael's code, and couldn't find any differences. Best, Dave Quote Link to comment
Ton Plomp Posted October 12, 2007 Report Share Posted October 12, 2007 QUOTE(DaveKielpinski @ Oct 11 2007, 11:13 AM) I did add another event case to the Facade as Michael suggested, with just a indicator to flag whether the event fired. Still the event never seems to fire! I double-checked my code against Michael's code, and couldn't find any differences.Best, Dave You should use a propery 'Value Signalling' Node. A local (or a 'Value' property) won't fire an event. Ton Quote Link to comment
DaveKielpinski Posted October 12, 2007 Author Report Share Posted October 12, 2007 QUOTE(tcplomp @ Oct 11 2007, 07:16 PM) You should use a propery 'Value Signalling' Node.A local (or a 'Value' property) won't fire an event. Ton I tried "Mouse Down" as an event as well, but still nothing. Sorry. Since this kind of thing seems to depend on all kinds of quasi-hidden settings, I'm attaching the whole VI. Best, Dave Quote Link to comment
Ton Plomp Posted October 12, 2007 Report Share Posted October 12, 2007 QUOTE(DaveKielpinski @ Oct 11 2007, 11:26 AM) I tried "Mouse Down" as an event as well, but still nothing. Sorry.Since this kind of thing seems to depend on all kinds of quasi-hidden settings, I'm attaching the whole VI. Best, Dave You kill the event registration refnum as soon as the exec change is changed to false (what happens if you load the XControl into a non-running VI. I think my method is the best..... If you want to correct me, please do Ton Quote Link to comment
Michael Aivaliotis Posted October 12, 2007 Report Share Posted October 12, 2007 I can only get this across with some real code. Find attached a working Xcontrol that does this in 8.2.1. Download File:post-2-1192098049.zip (8.2.1) Edit: In my rush i forgot to add the destroy code, but i think you can take it from there. Quote Link to comment
DaveKielpinski Posted October 13, 2007 Author Report Share Posted October 13, 2007 I got my control working by basically copying Michael. Ton's method also makes a lot of sense and I'd like to try it out, but I have to proceed with my project right now. QUOTE(Michael_Aivaliotis @ Oct 11 2007, 08:21 PM) Edit: In my rush i forgot to add the destroy code, but i think you can take it from there. Looking at other examples that don't use XControls, it seems like I should unregister the event just outside the Facade while loop when using Michael's method. However, when I add the unregistration there, the event never fires! Could I please have another hint? I think I still don't understand the underlying architecture here. Thanks, Dave Quote Link to comment
Ton Plomp Posted October 13, 2007 Report Share Posted October 13, 2007 QUOTE(DaveKielpinski @ Oct 12 2007, 11:27 AM) Looking at other examples that don't use XControls, it seems like I should unregister the event just outside the Facade while loop when using Michael's method. However, when I add the unregistration there, the event never fires!Could I please have another hint? I think I still don't understand the underlying architecture here. Thanks, Dave Well with unregistring you'll tell to LabVIEW I don't want this event to be triggered anymore. And that is just what LabVIEW is doing. As soon as the XControl is loaded into memory the XControl:Abilities:Facade_Ability_VI is run. You'll register for the event and immediatly destroy the event registration refnum. The proper way is to create the event registration refnum in the XControl:Abilities:Init_Ability_VI pass it around via the XControl:Abilities:State_Ability_control and destroy it in the XControl:Abilities:Uninit_Ability_VI. Ton Quote Link to comment
DaveKielpinski Posted October 14, 2007 Author Report Share Posted October 14, 2007 After a lot of tests, Michael's code works well for me... as long as there's only one event I need to register. I tried to extend Michael's code in a simple-minded way to handle multiple events, by adding another element to the RegEvents terminal. Suddenly I was no longer allowed to connect to the dynamic events terminals! I could still select any event I wanted for RegEvents, as long as there was only one event. I don't see why this should be. I made sure the dynamic event terminals were no longer linked to a specific refnum typedef by eliminating all dynamic events, restarting LabView, and replacing the dynamic event code. Still I couldn't connect to the dynamic events terminals. In case this is a basic problem with Michael's method, I've been trying to reverse-engineer Ton's method from the Boolean XControl on the code archive. However, I still can't get it working for even one event. Does the registered event have to be a user event? It seems that way from the code. Also, I could be missing something in the Display State Change event etc. Ton, I'm sure you have many calls on your time... but could I ask for a simple template similar to the one Michael provided? I think it could also help other people in the same situation. Best, Dave Quote Link to comment
Ton Plomp Posted October 14, 2007 Report Share Posted October 14, 2007 QUOTE(DaveKielpinski @ Oct 13 2007, 05:45 PM) ...by adding another element to the RegEvents terminal. Suddenly I was no longer allowed to connect to the dynamic events terminals! I could still select any event I wanted for RegEvents, as long as there was only one event. I don't see why this should be.... Ton, I'm sure you have many calls on your time... but could I ask for a simple template similar to the one Michael provided? I think it could also help other people in the same situation. Hi Dave, The problem is that event-registration refnums are stricly type def'd. This means that the first place you use the 'Event Registration Refnum'(ERR) you have to decide which type of events for which type of controls you want to use. In my case inside the 'Init Ability'. Then I right-click on the input terminal of the ERR and select 'Create control', go to the front panel of the Init ability and copy the control to the clipboard. Create a new type def Paste the control from the clipboard Save the control (make sure it's a typedef) Replace the control in the 'Init Ability' with the typedef Add the typedef as part of the 'State Ability' Now you can pass around the typedeff between the abilities In the 'Init ability' you use dummy references (a default reference of the correct datatype just like the LabVIEW example) When you think it is usefull to register use a valid reference and feed it to the correct event of the 'Register for Events' node (note: not connected terminals are not influenced) If you want to unregister use a dummy reference. Don't forget 'State changed?' Unregister at the 'Uninit ability Now you should be able to do dynamic event registration. The problem is you want dynamic diverse event registartion (I don't know how I should call it else), meaning at one moment you want to register for a mouse down and the next moment for a mouse move in the same frame this can't be done since LabVIEW is early binding. My nugget showed dynamic event registration meaning you can switch on and off the events. A lot of info is in http://forums.ni.com/ni/board/message?board.id=170&message.id=247057#M247057' target="_blank">this thread at the NI forums. If you want a quick example, post your XControl with good directions where you want to change the event registration. Good luck, Ton Quote Link to comment
DaveKielpinski Posted October 15, 2007 Author Report Share Posted October 15, 2007 With Ton's helpful suggestions, I was finally able to get Ton-style dynamic events working. My overall impression is that Michael's method (above) is very compact, because the event registration type definition is handled implicitly. Ton's method does that part explicitly, but this could lead to cleaner code. I've made a minimal example of Ton-style dynamic events in XControls, similar to the one Michael posted above for his method. Enjoy! Best, Dave Quote Link to comment
Michael Aivaliotis Posted October 15, 2007 Report Share Posted October 15, 2007 QUOTE(DaveKielpinski @ Oct 13 2007, 08:45 AM) I tried to extend Michael's code in a simple-minded way to handle multiple events, by adding another element to the RegEvents terminal. Suddenly I was no longer allowed to connect to the dynamic events terminals! I could still select any event I wanted for RegEvents, as long as there was only one event. I don't see why this should be... Sorry Dave. Here's how to add more items. We won't get into why this happens. Suffice to say that the registration refnum is typed to the data and because the uninitialized shift register is well, uninitialized, it retains the datatype. You need to type the wire by feeding in the registration refnum data from the outside of the while loop. We can't wire anything from outside the loop because this Facade vi runs only one iteration and the shift register retains the value from the previous run. To make a long story short here's what to do in 3 steps: Quote Link to comment
DaveKielpinski Posted October 15, 2007 Author Report Share Posted October 15, 2007 Hi Michael, That works great! It wasn't obvious to me, but maybe it should have been. I'm rapidly converging on code that does what I want, and now I know how to build it two ways! There is one more thing that is peculiar. My basic control is an array of clusters. I am building a run-time shortcut menu and then want to select an item from it. I can build the menu by registering a dynamic event "Shortcut Menu Activation?", with either a reference to the whole array or a reference to a cluster as my source. But if I want to get the user selection by registering "Shortcut Menu Selection (User)", it works only if the source is the reference to the whole array. If instead I drill down to the cluster reference, the event never fires! I have tried this both your way and Ton's way, and the behavior is the same, so I'm pretty sure it's an underlying thing about how LabView handles events. Is there some way that this behavior is intuitively obvious? Best, Dave Quote Link to comment
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.