Udostępnij za pośrednictwem


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.

image

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.

image

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.

image

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.

image

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

image

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 removed

  • Anonymous
    November 06, 2011
    How can I add a reference to system.drawing in LightSwitch? Its not displayed in my add references list. Thank you

  • Anonymous
    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, -Beth

  • Anonymous
    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