In this post I wanted to pull together some command tips that seem common when building features into the screens in your business applications. Some of them are floating around on the LightSwitch forums, community blogs, and samples but I thought having these in one place would be easier for folks. I use these techniques a lot when I’m building my own LightSwitch applications.
In this article I will show you:
- How to Create a Command
- How to Open a Open Another Screen (with or without Parameters)
- How to Open a Modal Dialog or Window
- How to Open the Browser & Navigate to a URL
- How to Open the Calculator (or other Windows System Programs)
- How to Open an “Open File” Dialog
- How to Open the Default Program for a File (like Office Documents)
So let’s get started!
First off let me start by showing you what I mean by “screen commands”. Commands are buttons (or links) that users click to perform some sort of action. You can add commands to any control like grids & textboxes as well as the screen itself. Take a look at the documentation
How to: Add a Custom Command to a Screen. Commands show up in the model on the left-hand side of the screen designer and are indicated by the pink method icons. You always have three commands by default – Close, Refresh and Save. Refresh and Save also appear in the Screen Command Bar by default when running the application.
Creating commands has two main parts – creating the actual button (or link), then writing the code to execute the command in the command_Execute method. (You can also control whether the command buttons are enabled or disabled by writing code in command_CanExecute method.) Commands can be buttons or links and typically are located in the ribbon at the top of the screen (called the Screen Command Bar) as well as on Data Grids or topmost group controls (called Command Bar) and these are displayed by default when you create a screen. However, you can add commands to any control on a screen that you want so you have a lot of flexibility on the placement of your commands. Here is a screen with a variety of commands:
To add a command to the Screen Command Bar or Command Bar for a group just select it in the screen designer and click the +Add button. Depending on the control LightSwitch will present a set of pre-built commands. On group controls that display data from a single entity, you can add a prebuilt command “Delete” that will delete the current record. On data grids and lists that work with multiple entities you can select a from a variety of commands for adding, editing and deleting records. You can also overwrite the default behavior of these commands by right-clicking on them and selecting “Override Code”.
To create a new custom command, select “New button” and then give it a method name. At that point it will appear in the model on the left of the screen designer. Once you create the button, right click on it and select “Edit Execute Code” to write the code for the command.
If you don’t see a Command Bar on a control (like a label, textbox, date picker, autocomplete box, etc.) just right-click on the control and then on the menu you will see "Add Button…”. You can also click “Add Layout Item” at the top of the screen designer and select “Add Button…”. If you’re running the application in screen customization mode then select the control and click the “Add button” icon at the top of the content tree. This gives you the flexibility to put commands anywhere on the screen you want.
Now that you understand how to create commands anywhere you want, here are some tips & tricks on some common code that you can write for your custom commands. Note that you can write this code in any of the screen methods, they are not limited to commands. Although that’s probably the most common place you will see custom code like this.
This one is very common and very simple in LightSwitch. In order to open a screen you use the Application object to access all your screens and call one of the “Show” methods.
Private Sub OpenMyScreen_Execute() ' Write your code here. Me.Application.ShowCreateNewCustomer() End Sub
You can also define optional and required parameters on screens. For instance if we create a screen based on a query that requires a parameter then LightSwitch will generate a screen field for us in the model that is used to feed the query. You can select this field and in the properties window you can indicate that it is a screen parameter as well as whether it is required or not.
Keep in mind that screens that have required parameters will not show up in the main navigation bar because they must be called in code.
Private Sub OpenMyScreen_Execute() ' Write your code here. Me.Application.ShowSearchCustomersByPostalCode("98052") End Sub
For a couple video demonstrations to see this in action please watch:
- How Do I: Pass a Parameter into a Screen from the Command Bar in a LightSwitch Application?
- How Do I: Open a Screen After Saving Another Screen in a LightSwitch Application?
There are also a couple methods on screens that allow up to pop up modal message boxes and input boxes. To present a message to the user you write the following:
Me.ShowMessageBox("This is the message")
You can also specify a caption and what kind of buttons you want on the message box like OK, OK and Cancel, Yes and No, etc. ShowMessageBox will return a value that indicates what the user chose. In this example I am want to ask the user if they are sure they want to delete a record. Since Delete is a pre-built command, just right-click on it in the screen designer and select “Override Code”. Then you can write the following:
Private Sub gridDeleteSelected_Execute() If Me.ShowMessageBox("Are you sure you want to delete this record?", "Delete", MessageBoxOption.YesNo) = Windows.MessageBoxResult.Yes Then Me.Customers.SelectedItem.Delete() End If End Sub
You can also get input from the user by using an input box. This is handy for presenting a message and requesting a single answer from the user.
Private Sub Search_Execute() If Me.CustomerPostalCode = "" Then Me.CustomerPostalCode = Me.ShowInputBox("Please enter a postal code to search for:", "Search") End If Me.CustomersByPostalCode.Load() End Sub
You can also open other modal windows that you create on the screen in the content tree. For instance, you may have a lot of fields on a record and you want to display the entire set of fields in a modal window when the user clicks a row command in a search screen instead of requiring them to scroll. Simply add the Selected Item to the bottom of your screen and then change the control type to a Modal Window. You can then lay out the fields exactly how you like. By default LightSwitch will create a button command for you to launch the modal window automatically but you can turn this off in the properties window by unchecking “Show Button”.
In order to launch this modal window from your own command you can call OpenModalWindow and pass it the Name of the Modal Window control:
Private Sub ShowAllFields_Execute() Me.OpenModalWindow("Customers_SelectedItem") End Sub
This video also shows a couple of these techniques:
This is a common one for sure. Maybe you want to open a browser to a specific site, or a report from SQL reporting services, or a SharePoint site. For instance say we have a textbox for our website address field. We can add a command to the control and then execute code to open the address. First you will need to add a reference to the System.Windows.Browser assembly. On the Solution Explorer flip to file view and then right-click on the Client project and select Add Reference.
Then on the .NET tab select System.Windows.Browser and then click OK.
Then you’ll need to add these imports at the very top of your code file:
Imports Microsoft.LightSwitch.Threading Imports System.Runtime.InteropServices.Automation
Now you can write code to open a browser to a specific URL:
Private Sub OpenSite_Execute() Dispatchers.Main.BeginInvoke( Sub() 'Dim uri As New Uri("http://www.bing.com") 'Go to a specific website Dim uri As New Uri(Me.Customer.WebSite) 'Go to website stored in the Customer.WebSite field If (AutomationFactory.IsAvailable) Then Dim shell = AutomationFactory.CreateObject("Shell.Application") shell.ShellExecute(uri.ToString) ElseIf (Not System.Windows.Application.Current.IsRunningOutOfBrowser) Then System.Windows.Browser.HtmlPage.Window.Navigate(uri, "_blank") End If End Sub) End Sub
Notice that we need to make sure we always call this code from the Main UI thread. If you don’t you will get an error if you are running LightSwitch as a browser application. When running in desktop mode the AutomationFactory.IsAvailable is true so that means we need to open the default browser. If we are already in the browser, then we can simply navigate to a new page.
You can also do a lot of other things in desktop mode like access the Windows file-system, open default programs, and use COM automation. Here’s some more tips for your desktop applications.
This is based on a tip I saw from Paul Patterson that I thought was pretty clever: Open the System Calculator with Interop. This is a nice productivity feature for users working with numerical values on your screen. Just like the previous example that opens the browser, you can open any Windows system programs with ShellExecute in desktop mode (this will not work in browser mode). First add this import to the top of your code file:
Then you can simply pass to ShellExecute the name of the Windows program you want to open:
Private Sub OpenProgram_Execute() Try If (AutomationFactory.IsAvailable) Then Dim shell = AutomationFactory.CreateObject("Shell.Application") shell.ShellExecute("calc.exe") 'Open the calculator shell.ShellExecute("notepad.exe") 'Open notepad shell.ShellExecute("mspaint.exe") 'Open Paint End If Catch ex As Exception Me.ShowMessageBox(ex.ToString) End Try End Sub
You may want to request a file from a user and you need to present the Open File Dialog. Here’s how you can do that. First add these imports to the top of your code file:
Imports Microsoft.LightSwitch.Threading Imports System.Runtime.InteropServices.Automation Imports System.Windows
Then write this code to open the Open File Dialog which prompts the user for a file:
Private Function GetFile(fileFilter As String) As IO.FileInfo Dim file As IO.FileInfo = Nothing 'This only works in desktop mode in LightSwitch. If AutomationFactory.IsAvailable Then 'You need to open the file dialog on the main thread. Dispatchers.Main.Invoke( Sub() Dim dlg As New Controls.OpenFileDialog dlg.Filter = fileFilter If dlg.ShowDialog = True Then file = dlg.File End If End Sub) End If Return file End Function
Then you could use this to guide the user into opening certain types of files by specifying a filter. Keep in mind that you can read from any file on the local machine but you are limited to writing or accessing the full path or details of the file to only those that come from trusted locations like the user’s My Document folder.
Private Sub FindFile_Execute() Try 'Request a text file: Dim myFile = GetFile("Text Files (*.txt)|*.txt") 'You can read from files anywhere on disk that the user has access to. ' However you can only write to files in trusted locations like My Documents. Using fs = myFile.OpenText() Me.ShowMessageBox(fs.ReadToEnd()) fs.Close() End Using 'Try to get the full path to the file. This will throw a SecurityException if ' the file is not from a trusted location like My Documents. Me.ShowMessageBox(myFile.FullName) Catch ex As System.Security.SecurityException Me.ShowMessageBox("Please select a file in your Documents, Music or Pictures folder.") Catch ex As Exception Me.ShowMessageBox(ex.ToString) End Try End Sub
Also note that in LightSwitch opening the OpenFileDialog will only work in Desktop applications which have elevated permissions. If you try to directly launch the OpenFileDialog in a browser-based application you will get a “Dialogs must be user-initiated” error message. This is because Silverlight dialogs (like OpenFileDialog) can only be opened from “user actions”, like a button clicked event handler. The reason why this won’t work with LightSwitch is because we invoke the button logic asynchronously, so the code is not considered to be “user-initiated”. For a work-around see the “Add a Simple Silverlight dialog” section of Matt Sampson’s post: How Do I Import Data While Running a LightSwitch Web Application.
If you want to open a file in it’s default program (specified by Windows) you can just use ShellExecute again. In this case you probably need to request the file from the user first so you can use the GetFile method in the previous tip above for that. Add these imports to the top of your code file:
Imports Microsoft.LightSwitch.Threading Imports System.Runtime.InteropServices.Automation Imports System.Windows
Then you can write code like this to request the file and then open it with the default program. Here’s a couple examples:
Private Sub OpenFile_Execute() Try If (AutomationFactory.IsAvailable) Then Dim shell = AutomationFactory.CreateObject("Shell.Application") 'Open a text file Dim textFile = GetFile("Text Files (*.txt)|*.txt") shell.ShellExecute(textFile.FullName) 'Open an Excel file Dim excelFile = GetFile("Excel Files (*.xlsx)|*.xlsx") shell.ShellExecute(excelFile.FullName) 'Open a Word Document Dim wordFile = GetFile("Word Files (*.docx)|*.docx") shell.ShellExecute(wordFile.FullName) End If Catch ex As System.Security.SecurityException Me.ShowMessageBox("Please select a file in your Documents, Music or Pictures folder.") Catch ex As Exception Me.ShowMessageBox(ex.ToString) End Try End Sub
I hope this post showed you some cool tips and tricks you can use on your screens and commands. Remember that you can put commands anywhere on your LightSwitch screens and there are a good set of prebuilt commands you can use for working with data. However if you need to provide users additional productivity features you can easily create custom commands and do almost anything you want.