Adding Static Images and Text on a LightSwitch Screen
UPDATE: This technique only applies to Visual Studio LightSwitch 2011. This is now built into LightSwitch in Visual Studio 2012. See: How to Add Images and Text to your LightSwitch Applications
A lot of times you want to display static images and text on your data entry screens, say a company logo or some help text presented in a label to guide the user on the screen. Adding images to buttons on screens is as easy as setting it in the properties window. However, when you want to display an image or static text on the screen directly you need to do a couple things. If you take a look at the Contoso Construction sample that I released a couple weeks ago, you will see that the “Home” screen displays a lot of static images and text in a completely customized screen layout. In this post I will show you how you can add static text and images to your LightSwitch screens by walking through this sample.
Screen Data Items and the Content Tree
By default, all the controls on screens you create in Visual Studio LightSwitch have to be bound to a data item. The screen designer displays all the data items in your view model on the left side. In the center is what’s called a “Content Tree”. Content Items make up the tree – these are the controls bound to each of the data items.
So when building screens in LightSwitch every control in the content tree must be bound to a data item. This data item can be a field on an entity, a collection of entities, or any other data item that you add to the view model. The screen templates help guide you in setting up a layout and all the data binding for a particular type of screen; be that a search screen, details screen, new data screen, etc. These templates are just starting points that you can customize further. In fact, the Home screen in this example is a completely custom layout. After selecting a template, I deleted all the items in the content tree and built up my own layout.
Data items can be basic properties like strings or integers, they can be methods that you call from screen code or buttons, or they can be entities that originate from queries. To add a data item manually to a screen click the “Add Data Item” button at the top of the screen designer. You can then specify the name and type of the data item. The home screen is a combination of all of these types of data items.
Setting Up Data Items
You add static images and text to the screen as local properties via the Add Data Item dialog and then lay them out in the content tree by dragging them from the view model on the left. So to add a static image to the screen first click “Add Data Item”, select Local Property, set the type to Image, and then name the property.
Click OK and it will appear in your view model on the left of the screen designer. Drag the data item where you want it in the content tree (if you don’t get it right you can run it later (F5) and move it around on the screen real time). Finally, change the control to an Image Viewer from Editor.
Repeat the same process for static text. To add static text to the screen first Add Data Item, select Local Property, set the type to String and then name the property. Drag the item into the content tree and then change the control to Label.
Initializing Static Properties
Because static screen properties do not originate from a data entity, you need to set the property value before the screen is displayed. You can do this in the screen’s InitializeDataWorkspace method which runs before any queries execute. You can access screen methods by dropping down the “Write Code” button at the top right of the screen designer. To set one image and one text static property you would write this code:
Private Sub Home_InitializeDataWorkspace(saveChangesTo As List(Of IDataService))
' Initialize text properties
Text_Title = "Contoso Construction Project Manager"
' Initialize image properties
Image_Logo = MyImageHelper.GetImageByName("logo.png")
End Sub
In order to load static images you need to switch to file view, right-click on the Client project’s \Resources folder and select Add –> Existing Item. Browse for the image and then set the build action to “Embedded Resource”.
Next you need to write some code to load the image. In the Contoso Construction sample application it uses static images in a variety of screens so I created a helper class called MyImageHelper that can be used from anywhere in the client code. While in file view, right-click on the \UserCode folder in the Client project and select Add –> Class. Name it MyImageHelper and create a static (Shared) method that loads the image.
''' <summary>
''' This class makes it easy to load images from the client project.
''' Images should be placed in the Client project \Resources folder
''' with Build Action set to "Embedded Resource"
''' </summary>
''' <remarks></remarks>
Public Class MyImageHelper
Public Shared Function GetImageByName(fileName As String) As Byte()
Dim assembly As Reflection.Assembly = Reflection.Assembly.GetExecutingAssembly()
Dim stream As Stream = assembly.GetManifestResourceStream(fileName)
Return GetStreamAsByteArray(stream)
End Function
Private Shared Function GetStreamAsByteArray(
ByVal stream As System.IO.Stream) As Byte()
If stream IsNot Nothing Then
Dim streamLength As Integer = Convert.ToInt32(stream.Length)
Dim fileData(streamLength - 1) As Byte
stream.Read(fileData, 0, streamLength)
stream.Close()
Return fileData
Else
Return Nothing
End If
End Function
End Class
You can add any custom code you need to the client this way. You have a lot of flexibility to add your own custom code and classes to LightSwitch and this is one simple example that show's how you can add static text and images to screens.
Enjoy!
Comments
Anonymous
June 15, 2011
Thank You for this help! Have You help for next problem? Is there a way to use the Enter key instead of TAB to move between textboxes and combobox in LightSwitch? Thank you!Anonymous
June 16, 2011
Useful info, as always, Beth. Thanks.Anonymous
July 12, 2011
For some reason my app doesn't bring the images, the image is just empty square. I converted the helper class to C# so maybe that's where I'm going wrong. This is the code (no indication of any error though): using System.Reflection; using System.IO; ... public class MyImageHelper { public static byte[] GetImageByName(string fileName) { Assembly assembly = Assembly.GetExecutingAssembly(); Stream stream = assembly.GetManifestResourceStream(fileName); return GetStreamAsByteArray(stream); } private static byte[] GetStreamAsByteArray(Stream stream) { if (stream != null) { int streamLength = Convert.ToInt32(stream.Length); byte[] fileData = new byte[streamLength]; stream.Read(fileData, 0, streamLength); stream.Close(); return fileData; } else { return null; } } } Another question: how do you hide names of labelsimages etc. I can't delete anything from DisplayName as it always comes back to be exactly the same as Name and I can't set Name to blank obviously.Anonymous
August 18, 2011
I have the same problem as gregid: the image is not loaded in a to C# converted ImageHelper. assembly.GetManifestResourceStream(fileName) returns null. The odd thing is that according to relector, GetManifestResourceStream() should throw a new NotImplementedException(), wich it doesn't. Is there anyone with a working C# example? @gregid: you can set the Label Position property of the Image to None. This will hide the image label.Anonymous
August 26, 2011
I'm having the same problem. A validation error appears saying that a value is required for my MyImage property.Anonymous
August 27, 2011
I fixed by problem. I think it was my namespaces that were wrong. Strange that I did not get a runtime error, a blank square just appears. Here's my working C# example that I found after searching: public static class MyImageHelper { public static byte[] GetImageByName(string filename) { System.Reflection.Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly(); Stream stream = assembly.GetManifestResourceStream(typeof(LightSwitchApplication.MainMenu).Namespace + ".Resources." + filename); return GetStreamAsByteArray(stream); } private static byte[] GetStreamAsByteArray(System.IO.Stream stream) { int streamLength = Convert.ToInt32(stream.Length); byte[] fileData = new byte[streamLength]; stream.Read(fileData, 0, streamLength); stream.Close(); return fileData; } }Anonymous
September 11, 2011
The comment has been removedAnonymous
November 06, 2011
How can I add a reference to system.drawing in LightSwitch? Its not displayed in my add references list. Thank youAnonymous
November 19, 2011
Stream stImage = assembly.GetManifestResourceStream("myimage.png"); it returns null.... what is the problem?Anonymous
April 26, 2012
I want to make a project with C# code. And I can do from 1st step to "Initializing Static Properties" But i can't write code in class "MyImageHelper.cs", this code isn't C#. Can you help me, please?Anonymous
April 30, 2012
@Newbie, There is C# version of this code in the Course Manager Sample: code.msdn.microsoft.com/LightSwitch-Course-Manager-c5608897 Note: You do not need this helper method if you are using LightSwitch in Visual Studio 11 (LightSwitch version 2). Static images & text are now supported in the designer. Cheers, -BethAnonymous
June 14, 2014
I got the same issue as Ray Cacciatori and some of the others but his fix didn't work for me. Seems my problem began when I click 'write code' dropdown and select initializedataworkspace I got this: Private Sub Home_InitializeDataWorkspace(saveChangesTo As System.Collections.Generic.List(Of Microsoft.LightSwitch.IDataService)) But BethMa solution looked like this: Home_InitializeDataWorkspace(saveChangesTo As List(Of IDataService)) worked ok after that if it is version specific but I was using 2011 version 10 sp1 Thanks