Change LightSwitch Screen Display Name in Code

[dropcap sid="dropcap-1342753418"]I[/dropcap]n some scenarios, there is the need to dynamically change the display name for one or more screens (and thus the associated menu items) in a LightSwitch application. This most often happens as part of supporting multiple localizations, but comes up in other cases as well. Luckily, this is a pretty easy task, but it’s not immediately obvious how to do it; it takes some digging through ill documented object trees to find the right objects.

First, a caveat: you need to explicitly set the display name for any screen you want to handle in this way. If you leave the default display name which LightSwitch generates for you, then LightSwitch won’t decorate the IScreenDefinition with the DisplayName attribute. And as of yet, I haven’t discovered a way to add additional attributes at runtime.

Update: You can add attributes by casting the Attributes property as ModelItemCollection<IAttribute>, so the previous paragraph no longer applies.

In your code, you make use of the Application.Details.GetModel() method. You need to enumerate the GlobalItems of type IScreenDefinition and find the screen you want.  Then search the Attributes of the screen for an attribute of type DisplayName (or add one if not already present). As an example, here’s helper class:

using System;
using System.Linq;
using LightSwitchApplication;
using Microsoft.LightSwitch.Model;
using Microsoft.LightSwitch.Model.Storage;

namespace LightSwitchApplication.UserCode
{
    public static class DisplayNameHelpers
    {

        public static void SetScreenDisplayName(string name, string newDisplayName)
        {
            var screen = Application.Current.Details.GetModel().GlobalItems.OfType<IScreenDefinition>().Where(s => s.Name == name).SingleOrDefault();
            if (screen == null)
                throw new ArgumentException("Screen name not valid.");
            SetModelItemDisplayName(screen, newDisplayName);
        }

        public static void SetGroupDisplayName(string name, string newDisplayName)
        {
            var group = Application.Current.Details.GetModel().NavigationItems.OfType<INamedItem>().Where(s => s.Name == name).SingleOrDefault();
            if (group == null)
                throw new ArgumentException("Group name not valid.");
            SetModelItemDisplayName(group, newDisplayName);
        }

        private static void SetModelItemDisplayName(IModelItem modelItem, string newDisplayName)
        {
            var displayName = modelItem.Attributes.OfType<DisplayName>().SingleOrDefault();
            if (displayName != null)
                displayName.Value = newDisplayName;
            else
            {
                displayName = new DisplayName() { Value = newDisplayName };
                ((ModelItemCollection<IAttribute>)modelItem.Attributes).Add(displayName);
            }
        }

    }
}

[box sid="box-1343156721" type="info"]Note that for LightSwitch 2011, you may need to add a reference in the Client subproject to the Microsoft.Lightswitch.Model.Xaml.Client.dll assembly.[/box]

Then to change the name of a screen, you can call

DisplayNameHelpers.SetScreenDisplayName("MyScreenName","The New Display Name");


To change the name of the “Tasks” navigation group, you could call

DisplayNameHelpers.SetGroupDisplayName("Tasks","The New Display Name");

Update:
It seems that this technique only works well for modifying the menu during the initial application startup. It works if you place your code in the Application_Initialize or Application_LoggedIn partial method (in the client’s Application.cs – right-click your application in Solution Explorer and choose “View Application Code (Client)” to access it). If you attempt to modify the menubar from one of your application’s screen, it may not.

6 thoughts on “Change LightSwitch Screen Display Name in Code

  1. Another brilliant post! As always, I’m impressed at the way you dig into the guts of Lightswitch, and pull out all sorts of useful tricks.

    Thanks

Comments are closed.