The easiest way to create business applications for the Desktop and the Cloud
In the beginning of The Wizard of Oz, the Munchkins urge Dorothy to “follow, follow, follow, follow, follow the Yellow Brick Road!”
Y’know… Dorothy probably wouldn’t have been very happy if the neighboring red brick road turned out to be shorter and/or devoid of lions, tigers, and bears.
Similarly, you probably wouldn’t be very happy if you wasted time implementing a piece of functionality, only to discover an easier way to do it. LightSwitch provides you as a developer ample flexibility to stray from the beaten path, but it also includes plenty of built-in functionality. Like what? Good question. Today, we’ll take a whirlwind tour of all the Screen Property Actions in LightSwitch and Cloud Business App projects that are at your disposal because… well… there are a lot of them, and why not take advantage of what’s available?
Screen Property Actions help you navigate between screens and/or perform operations within your application. These actions are accessible when you tap on a scalar property (returns entity), collection property (returns collection of entities), or button.
You can either write your own method (accessible within the scope of the specific screen you’re working with,) or choose an existing method. Existing methods include both those you may have already written for that screen and pre-defined convenience methods that take care of many of the common scenarios you’ll run into while building your application.
What exactly do these mystical convenience methods do? There are four kinds of convenience methods.
Let’s build a small sample application so we can see them in action. We’re going to assume you already know how to create screens in LightSwitch. If you are new to LightSwitch, please read this first.
First create a new “LightSwitch HTML Application” project and attach to the Northwind OData service, “http://services.odata.org/Northwind/Northwind.svc”. Select “None” for the Authentication Type, and click through to the next screen. Check “Entities” to include all entities, and press “Finish” to import the selected data items.
Now, right click the Screens folder, and click “Add Screen…” Select the Common Screen Set Template, set the screen data to Products, and check both the “Product Details” and “Product OrderDetails” boxes under “Additional Data to Include.” Press OK to generate a Common Screen Set.
You should see two screens – ViewProduct.lsml, and BrowseProducts.lsml (an Add/Edit screen is not generated because the database is read-only.) Also notice that Order_Details collection is included as one of the tabs of the generated ViewProduct Screen because Product has a one to many relationship with Order_Detail and because we checked Product OrderDetails in the New Screen dialog.
Next add a View Details Screen for Order_Detail. Be sure to check “Use as Default Details Screen.”
Take a look at Solution Explorer. You should now have three screens – BrowseProducts.lsml, ViewProduct.lsml, and ViewOrder_Detail.lsml – as shown below.
Hit F5 to launch the app and start debugging. Click through the screens to see what you built – every navigation is brought to you by Screen Property Actions automagically wired up by the Common Screen Set template.
Pop quiz. What happens when you click on one of the items in the Order Details tab in the ViewProduct Screen? That’s right! It navigates to the ViewOrder_Detail Screen.
Let’s dig in and see why that happened. Stop debugging. Click on the Order_Details Tile List in the Order Details tab of the ViewProduct Screen, and locate the Item Tap action in the properties window.
Now click the viewSelected hyperlink to edit the action. As you can see, the action navigates to the selected item’s default view screen that we specified during screen creation.
“Whoa! That’s awesome! It totally read my mind!” you exclaim. “…but what else can we do?” Hmm… I don’t know – let’s try expanding that dropdown list over there.
Yikes! Wasn’t expecting that. Apparently we have plenty of options… but why???
The following table summarizes the functionality of the methods in the ItemTap Action dialog above. The ViewProduct screen references both the “Product” scalar property and the “Order_Details” collection property (see data members list on left side of screen designer). Therefore the methods specific to these properties are enumerated below their respective headers in the ItemTap Action dialog. The selection of "Navigation" methods, on the other hand, is common to all screens (though their parameters are unique). For clarity, every screen has an associated showScreen application method that allows you a tighter control over your input parameters if you so desire.
Scalar Property Methods
Collection Property Methods
Screen Methods (to navigate within current screen) and Application Methods (to navigate between screens)
Once you select a method, you may be required to fill in some additional information specifying the screen you’d like to navigate to and/or a property parameter.
First, you’ll be prompted to select which screen/tab/popup you would like to “Navigate To” because there may be multiple applicable screens. No need to fill it in for the show<Screen> application methods because that information is inferred.
In this case, we’ve only defined a single View screen for Order_Detail, so that’s the only screen we’ll show you.
Lastly, you may be prompted to specify the property you’d like to use as a parameter for the screen.
This information is inferred for all but the application methods that accept parameters (i.e. those associated with AddEdit and View screens.) As an example, open the ViewOrder_Detail screen and add a reference to the corresponding Product.
Open the tap action dialog for the Product property you just added.
To make this property navigate to the View screen for the associated Product, edit the tap action to use the showViewProduct method. Enter “Order_Detail” as the property parameter to access the Order_Detail currently associated with that screen, and “OrderDetail.Product” to access the associated Product property.
The process is a little more elaborate when navigating from a collection to a method that expects a scalar property parameter. Let’s say you wanted to use the showViewOrder_Detail method to navigate from the Order_Details collection in the ViewProduct Screen to the view screen for the Order_Detail item that was tapped (instead of using the preferred viewSelected method.) You could open up the ItemTap Action for the Order_Details Tile List, select the “showViewOrder_Detail” application method, and set the scalar property parameter (Order_Detail) to “Order_Details.selectedItem” to reference the selected item in the Order_Details collection.
As expected, you can continue chaining properties together. To specify the Product associated with the selected Order_Detail, use “Order_Details.selectedItem.Product".
And to specify a Category associated with that Product… you guessed it! “Order_Details.selectedItem.Product.Category”.
Of course, a more elegant solution in this particular case would be to specify “Product.Category” as the property parameter, but you get the gist.
Well that’s all for now. Questions, comments, complaints? We’d love to hear from you, so click your heels together three times and say ‘There’s no place like LightSwitch’ to leave a comment below or visit our forums. Happy item-tapping!
- Sara Itani, Software Developer, Cloud Business Apps
Nice Article. Would be nice if the Convenience Methods allowed hooks for beforeShown and afterClosed operations.
...or just have them generate and add the tap js to the screen code instead of hide the functionality in the model. That way users can have the convenience and also expand upon the generated code to utilize beforeShown and afterClosed operations, for example.
*Only available to document libraries
createOrUploadDocument * ,** ,***, ****
**Only works for document libraries having a relationship to a non-sharepoint entity
***Only works for Office Business App Template
****Only works for Office365 document libraries
Great ideas. Is there a specific use case or scenario you have in mind? Sharing that would help us reason better about future designs.
We're constantly working to balance ease of use and advanced functionality, so feedback like this is always helpful. Keep it coming!
Thanks for your constructive feedback. I've shared it with the team. I especially like how setting context-specific properties during navigation would facilitate screen reuse. I also agree that it would be valuable to provide more visibility into the overarching navigation structure.
I second Josh's comments that the code would be MUCH more useful to devs if it was "generated", rather than "hidden away". That way it would be available to be tweaked to suit scenarios that don't quite match the default scenario. Even better would be to have a setting where the dev can decide whether to have the code generated, or leave it hidden. Either a system-wide setting for all cases, or an option in the wizard screen to be selected on a case-by-case basis.
I rarely ever use the pre-wired option, because there's nearly always a need to do something before or after the screen has been opened. One very common use case is dynamically setting the screen's DisplayName. Having the wizard generate that code, which can then be modified to suit the particular need, would be awesome.
Increased tweak-ability of built-in actions. Gotcha.
Could you help me understand why using the screen's created method or a control's postRender isn't sufficient for dynamically changing the screen name in your scenario? Is there relevant information on the previous screen or action that you can't gather from the underlying data?