The easiest way to create business applications for the Desktop and the Cloud
Hello LightSwitchers! I hope you’re all having fun and building cool stuff with RTM. I apologize for the delay of this conclusion of the Course Manager series. In case you missed it, here are the previous posts:
In this post, we will walk through how to design a “Home” screen.
In LightSwitch, you can indicate a screen to be the “start-up screen” of the application. Meaning, the screen will be automatically launched when you start the application. In our case, we want to create a home screen that provides some entry points for different workflows when the user first starts the application.
Let’s first create blank screen to be our home screen. To create a blank screen, you can pick any screen template in the Add New Screen dialog and leave the Screen Data to be “(None).” In our case, we will pick list-detail screen template, name the screen “Home,” and leave the Screen Data “(None).”
Double click on Properties node in Solution Explore to open the application designer.
Select the “Screen Navigation” tab in the application designer. In the menu structure tree, select “Home” and click “Set” at the bottom. This will set the “Home” screen as the start-up screen of the application. Finally, use the up/down arrow buttons on the right to move the “Home” screen to the top of the menu.
If you hit F5 now, you will see the “Home” screen is automatically opened when you launch the application. The menu on the left also reflects the ordering you specified in the application designer.
We have a blank canvas on start-up. It’s time to use some creative juice in designing our home screen. Before we start, let’s draw out what we want to build… and this is what we have:
To sum up, we want:
Let’s draw some boxes around the picture and see how we could create this structure. There are essentially 2 big groups vertically stacked on top of each other:
Let’s go back to the IDE. Double click on “Home” in Solution Explorer to open the screen designer. We will first create the top and bottom group. Since they will be vertically stacked, change the root from “Columns Layout” to “Rows Layout.” Set the Vertical Alignment to “Top” in Properties window, so things will not stretch vertically.
Use the “Add” dropdown to add 2 groups under the Home screen node.
Since the top group horizontally stacks the logo and the text group, change the top group from Rows Layout to Columns Layout. The bottom group is a tab group, so we will use the Tabs Layout.
Next, we want to add a logo to the top group. This logo will be a static image. Meaning, it is an image file that you supply.
In LightSwitch, every visual element you find on the screen content tree needs to bind to some data. In most cases, they are data from the database (such as a student list or grid), or in our case, a static data property.
To create a static data, we need to add a local property. Click “Add Data Item” on the command bar to add a piece of data. In our case, we want a local property of type Image. Name the property “Image_Logo” and click OK.
In the screen designer, drag and drop the newly created Image_Logo to the screen content tree. Let’s put it under the top group we created earlier.
If you run the application now, you will see an image field on the screen:
This is great but not exactly what we want. First, we don’t need a label for “Image Logo.” Second, this is a static image, so we don’t want user to be able to update an image. We can easily take care of these. In the screen designer, change the image control from “Image Editor” to “Image Viewer.”
In Properties (with the Image Logo node selected), set Label Position to “None.”
While we’re at it, we can also change the image size.
If you run the application again, you will now see a blank image on the screen:
This is more like it… well, except there is no image.
Now, we need to wire up the Image_Logo property we created to an image file on the computer.
This process requires a bit of coding. In screen designer, click “Write Code” button in the command bar and select Home_InitializeDataWorkspace.
In the body of the method, assign Image_Logo property to an image file (I have a file called “logo.png”):
Image_Logo = GetImageByName("logo.png")
GetImageByName is a helper function that converts an image file into a byte array. Copy and paste the following helper functions to the screen code.
Private Function GetImageByName(fileName As String) As Byte()
Dim assembly As Reflection.Assembly = Reflection.Assembly.GetExecutingAssembly()
Dim stream As Stream = assembly.GetManifestResourceStream(fileName)
Private Function GetStreamAsByteArray(ByVal stream As System.IO.Stream) As Byte()
Dim streamLength As Integer = Convert.ToInt32(stream.Length)
Dim fileData(streamLength - 1) As Byte
stream.Read(fileData, 0, streamLength)
Now, we need to add the image file to the project (logo.png). In the Solution Explorer, switch from Logical View to File View.
Right click on the Client node. Select “Add” then “Existing Item.” This will launch a dialog for you to navigate and select your image file.
In this dialog, I will select my “logo.png” file and click Add. The image file will appear under the Client node.
With the image file selected, set the Build Action to “Embedded Resource” in Properties window.
If we run the application again, you will now see the image file you supplied in the screen.
Now we’d like to add some text next to the logo. We will first create a new group to hold this text (title, subtitle, and description). In the screen designer, add a new group below the logo node.
Adding static text follows the same concept as adding a static image. We will first create a piece of static data, in this case, a String (rather than an Image). Click “Add Data Item” button in the command bar, add a local property of type String. Name the property Text_Title and click OK.
Drag and drop the newly created property to the content tree (under the text group).
Change the control from Text Box to Label. Set Label Positions to “None” in Properties window. LightSwitch provides a set of pre-defined text styles for text-based controls. Let’s also set the Font Style property to “Heading1.”
We now need to assign the Text_Title property to some value. Click on Write Code button on the command bar. In screen code, add the following in Home_InitializeDataWorkspace method:
Text_Title = "School of Fine Art - Office of Registrar"
If we run the application now, you will see the title appear on the screen in a larger and bold font.
You can follow the same steps to add a subtitle and description (with different font styles) to the screen.
We’re now ready to move on to the bottom group. Before we begin, create some static images and text data to use for the bottom group. If you look at the Course Manger sample, I’ve added 4 additional images and 4 additional texts.
Now, if you look back at our drawing, we need a table under the tab control. The table consists of 4 columns and 2 rows. Why do we use a table layout instead of rows and columns layout here? Well, you certainly can. Table layout, however, lines things up better in this case. For example, if you need a larger margin between and image and text, you can adjust it for the entire column at once (instead of lining it up one by one). Plus, I need an excuse to show you the table layout J
Add a new group under the tab group. Change the control to Table Layout. Set the Horizontal alignment to “Left” in the Properties window.
Add 4 groups under the Table Layout. These groups will automatically be using the TableColumn Layout. They represent the 4 columns in our table.
The first column contains 2 images. So I will drag and drop 2 image data to the content tree.
Similarly, drag and drop 2 texts to the 2nd column, 2 images to 3rd column, and 2 texts to the 4th column. Change the controls from Image Editor to Image Viewer and Text Box to Label. Set their Label Position property to “None.” If you also set the Height property of the Label to “Auto,” the text will wrap nicely within a table cell.
Let’s run the application and see where we are.
We’re almost there! We just need to add a link for each workflow. We can achieve this by adding a command that navigates to a workflow screen. Right click on the Text Search node and select Add Button.
In the dialog, name the method SearchStudents and click OK.
A command will be added. Change the control from Button to Link.
Double click on the command to go to the code. Write the following to launch the SearchStudent screen when the user clicks on the command.
Private Sub SearchStudents_Execute()
Follow the same steps to add the rest of links. Let’s run the application to see the home screen!
In this post, we learned how to set the start-up screen. We added static images and texts (with different fonts). Finally we use the table layout to line up items on our home screen. If you’ve been following the previous blog posts, you have just created the Course Manager app from scratch!
This concludes our Course Manager Sample series. Thank you very much for following!
This looks good. One problem though, I can not add Home_InitializeDataWorkspace added to the screen code. In fact, I can not add or view screen code for my home page but I can for others. Any help will be greatly appreciated.
@Josh - When you click on the arrow in the "Write Code" button in the screen designer command bar (see screenshot in the post), do you see a dropdown list with Home_InitializeDataWorkspace in it? I assume you named the screen "Home" :)
Great tutorial, Andy. Thanks for the good info.
very helpful - thanks
@Andy - Very timely article since I was already working on a home page for a LS app. Any way to hide the 1 px border around images?
@Doc - Unfortunately, there is no easy to turn the image border off. You might consider creating a custom image control, especially if you're reusing the same image across screens (such as a logo). Beth Massi has a nice blog about "Building your own Static Image Control" blogs.msdn.com/.../adding-static-images-and-logos-to-lightswitch-applications.aspx. Here is a related forum thread as well: social.msdn.microsoft.com/.../5ca90bd1-0785-4a4b-ab14-33e8ff701101.
Hope that helps!
Thank you, Andy. This is exactly what I needed and it works perfectly!
It would be nice to have additional control over margins and padding on the controls. I had to add a spacer between two of my columns for my particular layout. Also, the link always aligns to the right. These tools are very powerful, but the layout takes me back to 1999.
@swhitley - thank you for the feedback! I understand sometimes you have to jump through some hoops to get certain layouts the way you want. I'd encourage you to submit suggestions/ideas on your User Voice site: visualstudio.uservoice.com/.../127959-visual-studio-lightswitch. We’d love to hear what control properties people find useful.
Thanks for this Andy, exactly what I was looking for. I decided to store the data in an 'application settings' key value table. Now the performance isn't fantastic, but at least I don't need to re-compile the app to change some text or an image on the front screen.
Could you add the code for the GetImageByName and GetStreamAsByteArray methods in C#, because I got an error (Object reference not set to an instance of an object.) ?
Andy, one of the things that makes this a great article, rather than just good, is your use of diagrams to explain what it is you want to do. What application did you use to generate these... I must have them :)
You can now do all of this (and quite a bit more) without needing all those screen properties, and without writing a single line of code.
If you look at the free custom controls I released for Lightswitch (Visual Studio Gallery page visualstudiogallery.msdn.microsoft.com/9c342bec-e3e5-4c08-9993-35ccb26d3c9f), you will see a static image viewer, which you just drop on the screen and choose the image, a static text control, which you set the text directly in the control's settings, and some other controls for layout, spacing and so on.
Due to the way Lightswitch works, you'll still need one screen property, as every control needs to be bound to something, but it can be any type of property, and isn't actually used. You can bind all the static image and text controls to the one screen property.
Hope this is useful to anyone reading this excellent blog. It saves a boat load of time and effort when setting up screens like this one.
Thanks for your great articles Andy.
I needed to place the image file into a 'resources' folder rather than directly under the client.
Is there a way to remove the x (close function) from the Home tab so it stays visible all the time?