Partilhar via


“I Command You!” - LightSwitch Screen Commands Tips & Tricks

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:

So let’s get started!

How to Create a Command

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.

image

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:

image

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.

image

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 image at the top of the content tree. This gives you the flexibility to put commands anywhere on the screen you want.

image

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.

How to Open Another Screen (with or without Parameters)

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.

image

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 to Open A Modal Dialog or Window

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”.

image

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

image

This video also shows a couple of these techniques:

How to Open the Browser & Navigate to a URL

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.

image_thumb12_thumb

Then on the .NET tab select System.Windows.Browser and then click OK.

image

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("https://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.

How to Open the Calculator (or other Windows System Programs)

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:

 Imports System.Runtime.InteropServices.Automation

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

How to Open an “Open File” Dialog

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.

How to Open the Default Program for a File (like Office Documents)

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

Wrap Up

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.

Enjoy!

Comments

  • Anonymous
    October 07, 2011
    I love this kind of stuff ;-) Great!

  • Anonymous
    October 08, 2011
    perfect time, without these tips and training, I would not know what to do with lightswitch. Thanks again for a wonderful work. Rachida

  • Anonymous
    October 12, 2011
    The comment has been removed

  • Anonymous
    November 08, 2011
    Hi... Im from Brasil... Great !!! Please... a need one example for INPUT PASSWORD !!!

  • Anonymous
    November 12, 2011
    Useful as always. Thanks Beth

  • Anonymous
    February 06, 2012
    Very useful information. Thanks for the post!

  • Anonymous
    February 27, 2012
    Thanks!  This made it easy to launch an SSRS report from my Lightswitch screen in a new browser window.  I appreciate the info!

  • Anonymous
    March 31, 2012
    The comment has been removed

  • Anonymous
    April 18, 2012
    Beth, In the section of the article, "How to Open the Default Program for a File", how would you open a file that you have saved in a database as a byte array?  I am currently using the SaveFileDialog to prompt the user for a save location to download the file, but I would rather have an "Open" option to display the byte array w/o having to save it to disk.

  • Anonymous
    May 05, 2012
    Hi Beth, Thanks so much for the tutorials. I have found the videos very helpful but am struggling with a problem with passing values betweem screens. I have linked three sql tables to a create screen and would like to populate the  "use existing record" create screen with values from an existing record. IE Make a copy of the record but create a new instance. As I have only been using lightswitch for 2 weeks I am not sure if it is possible to pass values from 3 different datagrids into a create screen? Your assistance would be greatly appreciated and I hope my description of the problem is clear and correct! Regards, Matt

  • Anonymous
    May 10, 2012
    @Leon - I'd take a look at the Document toolkit extension: www.microsoft.com/.../firstfloor @Matt - Take a look at this video for info on how to pass parameters to screens: msdn.microsoft.com/.../ff961919 HTH, -Beth

  • Anonymous
    July 10, 2012
    The comment has been removed

  • Anonymous
    January 28, 2013
    The comment has been removed

  • Anonymous
    July 31, 2013
    Hi Beth, Do you have an article like this one but for the HTML client?   Thanks Miguel

  • Anonymous
    August 11, 2013
    Hi Beth Is it possible to call a command in a Custom Control, Visual Studio 2012 Regards, Dean

  • Anonymous
    October 06, 2013
    Thank you for nice article.  I am using MS SQL Report Builder for my reports and would like to assemble a connection string from a button in lightswitch 2012. I created a report called "C:DemoDemoReport.rdl" and references a table named "categories".  In the button "Private Sub CategoriesReport_Execute()" method, I have the following that actually works but only brings up the "Report Builder" whereupon I must "Run" the file "DemoReport.rdl.  I would like to bring up "Report Builder" and run the file "DemoReport.rdl" automatically. Would you please help me with the connection string.  Thank you. THIS WORKS:             Dim uri As New Uri("C:Program Files (x86)Microsoft SQL ServerReport Builder 3.0MSReportBuilder.exe")             If (System.Runtime.InteropServices.Automation.AutomationFactory.IsAvailable) Then                 ' This is a desktop app, so shell to the default browser                 Dim shell = System.Runtime.InteropServices.Automation.AutomationFactory.CreateObject("Shell.Application")                 shell.ShellExecute(uri.ToString)                 'shell.ShellExecute("C:DemosDemoReport.rdl")             ElseIf (Not System.Windows.Application.Current.IsRunningOutOfBrowser) Then                 ' This is a web app, so navigate to the page                 System.Windows.Browser.HtmlPage.Window.Navigate(uri, "_blank")             End If I would also like to open the report in the Explorer Browser, similar to your Contoso connection string example:         Dim uri As New Uri("www.contoso.com/.../ReportViewer.aspx) Thank you, Edward Piccoli enpiccoli@msn.com

  • Anonymous
    October 08, 2013
    @Edward -- you may want to look at this forum thread: social.msdn.microsoft.com/.../how-to-open-report-in-report-buildermicrosoft-sql-report-service-using-programatically-using HTH, -Beth

  • Anonymous
    October 08, 2013
    is there a way to get the URL opens on Mac? as it seems to only work on windows

  • Anonymous
    March 06, 2014
    How do you add an 'Exit' submenu item to the menu?

  • Anonymous
    September 19, 2014
    Hi, thanks, just a question, how do I add an inputbox result to an entity table via code after entry by user? Is is possible to ShowCreateNew... as a modal screen? Can this also include a parameter?

  • Anonymous
    October 15, 2014
    Hi Beth, I was wondering how you can open up native apps from lightswitch such as bing maps or google maps app