Fetal Development Pictures: a custom collection control

This week, I’ve been working on a LightSwitch custom collection control (LS Desktop Extensibility Toolkit) that shows a collection of ‘sticky notes’ for a given entity.  It was a private project so I cannot share the code right now (give it some weeks), but I did take some screenshots that show you the fetal development process.

Image 008

Image 009

Image 010

Image 011

Image 012

Image 013

Image 014

Image 017

Image 023

Image 101

Image 102

Hopefully these spark your imagination, it’s a pity not more people share actual LightSwitch projects, finished or in progress.

Keep rocking LS!

 

Quick tip: LS Excel importer speed improvements

The LightSwitch desktop client has a great extension that lets you load an excel file, map the columns to your LightSwitch entities, then import the data in your application.

The source code is available and provides a great start to build an excel importer that fits your needs specifically.  Besides a couple of functional shortcomings (find the line ‘//TODO multiple worksheets’), it has one really big technical flaw: it uses COM interop to read the excel file.

This means that it’s really slow (3 mins for a 5k line file), the end-user MUST have excel installed on the local pc AND it works for Out-Of-Browser apps only.

However, an excel file is really just a zip that contains a couple of XML files.  If you replace the COM interop with some code that unzips the file and interprets those XML files instead, it becomes really fast (less than a second for a 5k line file), the end-user does not need to have excel installed on the local pc AND it works for in-browser apps too!

SilverlightShow.Com has a really great post on how to read and excel file via XML parsing.  It returns the data as an IEnumerable of Dictionary of ColumnName -> CellValue though, so you’ll need to mold it a bit:

                        FileInfo f = dialog.File;
                        XLSXReader reader = new XLSXReader(f);                        
                        var data = reader.GetData(reader.GetListSubItems().First()).ToArray();

                        var columns = data[0].Keys.OfType().ToList();
                        object[,] values = new object[data.Length, columns.Count];

                        for (int r = 0; r < data.Length; r++)
                        {
                            var row = data[r];
                            foreach (var c in row.Keys)
                            {
                                values[r, columns.IndexOf(c)] = row[c];
                            }
                        }

                        _excelDocRange = values;

Keep rocking LS!

Jan

 

PS:sorry my content is reaching you in ‘waves’, but I have so many pots cooking at the same time I often do not find the time to serve you a decent lunch…  ;-)

Breaking MVVM: Change the background color of a control in a LightSwitch desktop app

A couple of months ago I was faced with the following hacking challenge:

One of our entities has pairs of properties: StreetName and StreetNameAdv, City and CityAdv, Name and NameAdv, …  For each of these pairs, the screen should clearly color the background of the xx property, if the value does not match the xxAdv property.

Or, put in pixels:
fieldhighlighting

If you happen to be familiar with the LightSwitch MVVM implementation, you’ll realize this is not a walk in the park, because the controls that form the View layer are tucked away in a LightSwitch theme extension.  Trust me, that’s one area you’ll want to stay away from unless you’re really experienced with LightSwitch extensibility.

So the easier way, in this case… Is to break our MVVM layering…

[Audience gasps]

Breaking MVVM: episode one: Finding ViewModel ContentItems bound to a particular property on the Model.

This code snippet contains an extension method to track all ContentItems that are displaying a particular property.  The first step is to retrieve an IScreenPresentationView from an IScreenObject.  We do this with the help of the ScreenViewService, a class intended to help out people with their custom shells.  From there, it’s a recursive walk down the children of this root, and find out who’s displaying what.

Breaking MVVM: episode two: Finding ContentPresenters and their controls.

Once you have a ContentItem, it’s a walk in the park to get all associated presenters (the’View’ layer): call the GetAssociatedPresenters method.

Almost there.  What you have now is a bunch of IContentItemPresenters, which give you access to the Silverlight controls used by your selected LightSwitch theme via their .Visual property.  However, these Silverlight controls are usually a lot more complex than a mere ‘TextBox’ or ‘Label’ here and there.  Hence, you’ll have to take a recursive dive in the visual tree to find the real control you need to color:

Mission accomplished!  Well, these code snippets are really only the ‘helper methods’ to help you break your MVVM layering.  Depending on your needs, you’ll need some additional code.  I have a sample that demonstrates the entire thing in action.  Feel free to grab it from my skydrive!  

Keep rocking LS!

Jan

Do you serve your Azure Web Site hot or cold (Updated)?

9 nights after my previous inscription, my little birds in the realm have whispered me tales of this new Azure Web Sites feature called “Always On support“.  Thank you for bringing this to my attention, Jürgen, you shall be rewarded 2 extra virgins.

Apparently, them cloud people have a new weapon to protect against winter turning your web sites cold…

image_1A5E2489

Keep in mind that your coins shall be taken by the hour that your Web Site are hot, so some of us might stick to the iron price of an Azure Scheduled Job.

Keep rocking LS!

Jan

A trio of self-explanatory exceptions

Good: there’s a Visual Studio extension that allows you to bind F1 (or another shortcut) to “open a new browser and search for the currently highlighted text”.  Saves me at least 24 keystrokes per day, or over 100k keystrokes before I get to retire.

Bad: sometimes you get an exception that looks extremely self-explanatory, but the obvious solution, nor any of the search result web pages seems to solve your issue.

Even worse: had three of those in one day.  I thought I would save someone else some trouble some day, and post about these three ‘self-explanatory’ exceptions, and explain what the description really meant to me.

OutOfMemoryException: Out of memory.

[OutOfMemoryException: Out of memory.]
   System.Drawing.Graphics.FromHdcInternal(IntPtr hdc) +1151157
   System.Drawing.Font.ToLogFont(Object logFont) +145
   System.Drawing.Font.ToHfont() +98
   Telerik.Reporting.Pdf.Fonts.TrueType.FontReader.GetFontData(Font font, Boolean& isTTC) +101

What is seems to mean: “You are out of memory.  Consider scaling out.”

What it really meant in my case: “You are trying to run a Telerik report or another operation that requires GDI+ from an Azure Web Site.  Azure Web Sites do not support GDI+. Consider deploying to an Azure Cloud Service instead, or… Ah, screw it, this exception message is too long, let me just throw you an out of memory exception instead.”

What I did: deployed to an Azure Cloud Service.  Sent the bill to Telerik.  No response yet.

Unable to find any implementation of the contract: ‘Microsoft.LightSwitch.BaseServices.Logging.Internal.ILoggingService’

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.ComponentModel.Composition.CompositionException: The composition produced a single composition error. The root cause is provided below. Review the CompositionException.Errors property for more detailed information.

1) Unable to find any implementation of the contract: 'Microsoft.LightSwitch.BaseServices.Logging.Internal.ILoggingService'

What is seems to mean: “Your IOC container, MEF, is missing an implementation of the ILoggingService.”

What it really meant in my case: “You tried to instantiate a ServerApplicationContext, but something went wrong.  Whatever went wrong will be logged, let me just get a logger from the MEF container that is created when you instantiate a ServerApplicationContext.  Oooo crap”.

What I did: found that some of my ServerApplicationContexts wasn’t properly being disposed of.  Always wrap your IDisposables in a using statement.

System.Security.SecurityException: Dialogs must be user-initiated

What is seems to mean: “You are trying to show a Print/Save/Open dialog from a sandboxed Silverlight application, but the user asked for no such thing.”

What it really meant in my case: “You are trying to show a Print/Save/Open dialog from a sandboxed Silverlight application, and the user did just click a Print/Save/Open button.  However, somewhere deeply buried in MSDN documentation it says that between the user instantiated event and the point where you show a dialog, there can only be a very limited amount of time.  The length of this time limit isn’t specified in an absolute number of milliseconds, but as ‘the number of milliseconds you really need, minus 5‘.”

What I did: removed all breakpoints, and split up the processing of the report and the actual printing in a two-step process.  This way, when the report is fully rendered, the user has to click a button “ok well print it then” which only invokes the actual print dialog.

Your turn, Dr. Watson.

Do you serve your Azure Web Site hot or cold?

Internet tweeps seem to be in a debate about where the coldest spot right now would be: Fargo (ND), Mars, Winnipeg (Canada) or Yakutsk (Russia) (in that order, apparently). Honestly, that’s one race I’ll gladly pass on.  I hate cold, I’ll take hot over cold any day.  The weather, my coffee, my wife, my Azure Web Sites, …

Wait, never heard of cold or hot Azure Web Sites?

Azure Web Sites are running in a shared pool of resources.  To optimize this resource pool, the smart engineers at MS have decided that if one site in that pool does not have any user activity for roughly 20 minutes, resources are no longer allocated for that site.  The IIS process for that site gets killed, and the site is now ‘cold’.  After going cold, when a user connects to the site, Azure reloads your site and the site is now ‘warm’ until the next span of 20 minutes without user activity. As part of resource optimization, this 20 minute span may even be shortened if the other web sites in your web site’s resource pool are very busy (although it is believed never to go below 5 minutes).

I love Azure Web Sites and they are by far the most hassle-free way to deploy a LightSwitch application.  However, I do have a couple of problems with serving up cold web sites to my customers:

  • The first time a user connects after inactivity, he/she has the perceived user experience that the web site is slow, or needs to ‘wake up’.  This usually happens twice a day (mornings and after lunch).  If your web site is rather large (which happens quickly with LightSwitch apps), the call might even time out before Azure has your server process fully warmed up.  Two timeouts per day, for LOB apps with a small amount of users especially, does not boost customer confidence.
  • Even worse, if your web site happened to be a LightSwitch Desktop app (Silverlight OOB), that first call happens to be the SL app checking if the currently installed version still matches the server.  If that call times out, the app displays a big red warning sign stating that the application could not check for updates and could not be started.  Ouch!
  • Sometimes you might want to start a background thread to do a limited amount of simple event processing (not the most reliable or scalable architecture, but by far the cheapest).  When you do, you do not want to depend on user activity to keep this process from going cold.

Thankfully, if you decide there’s a good reason why your web site should not go cold, there are a number of good solutions to keep the oven burning.  One is the built-in feature called ‘Always On‘ (added after this article originally was published), this article will demonstrate the same effect using Mobile Services’ Job Scheduler.

An Azure scheduled job consist out of two parts: how often do you want to run, and what do you want to run.

Schedule your job to run every 5 minutes.  Image 279

I’ve done some test and these ’5 minutes’ do not have a millisecond precision, but close enough.  Besides: 5 minutes is the absolute shortest amount of time before your site goes cold if all other web sites in your pool are really busy, so we should be covered.

Then, time to paste some JavaScript in the ‘script’ tab.  The only thing the script needs to do, really, is generate some ‘user activity’ in our Azure Web Site.

require('request').get({ url: "https://mysite.azurewebsites.net/HTMLClient/default.htm" });

Keeping Azure Web Sites alive means providing ‘incoming user activity’, like any HTTP GET to a web page or Web API, etc…  You can use a single script to keep as many sites alive as you want.  Azure should give you one free job, but it has a limitation of 16667 API calls and 165 outgoing MB per day.  This means that at a pace of 1 call per site per 5 mins, you can keep 57 sites warm without spending a single penny.

In a final note, a couple of days after this writing article, an update was published adding an Azure feature called ‘Always on’.  This also means ‘always billed’, and if you’re really cheap ( like me) and have more than 57 sites to keep warm (also… like me) then you could consider skipping some hours.  When you do, though, don’t forget that all Azure Servers, no matter where they are deployed, always run on UTC time…

https://gist.github.com/janvanderhaegen/8301294

Keep rocking LS!

Jan

LightSwitch and T4 code generation

If you find yourself writing ‘similar’ and ‘repetitive’ code, you might want to look into custom code generation.

Code generator tools generate their code based on some kind of meta-data.  LightSwitch is partly a code-generator tool itself: what you do as a developer in the Screen Designer, Query Designer or Entity Designer, is stored in LightSwitch Markup Language (lsml files, the meta-data that describes your application), and used to generate code for parts of your application at compile time, and to interpret other parts at compile time.

Because your LightSwitch application already has this meta-data-driven approach, it’s extremely easy to do additional code generation yourself!

I started by downloading some tools, Tangible T4 editor came highly recommended for code coloring and “File>New Item” templates.  After installation and VS reboot, I added a new file and from the Tangible section in the Add New File dialog, selected “Advanced” template.

This generates a sample tt file (the T4 template) which interprets a piece of xml to generate a .cs file (any file is supported).  In the tt file, just swap out the hardcoded xml to load the lsml files you need (the path to your lsml files might be different!):

	XNamespace  schema = "http://schemas.microsoft.com/LightSwitch/2010/xaml/model";
	string serviceLsml = System.IO.File.ReadAllText(
		System.IO.Path.GetDirectoryName(this.Host.TemplateFile) + "\\..\\TESS.DataWarehouse\\TESS.DataWarehouse.Server\\Properties\\Service.lsml");
	System.Xml.Linq.XDocument XmlDoc = System.Xml.Linq.XDocument.Parse(serviceLsml);

Then just use your XDocument wizardry to extract the information you need…

		foreach(var entityContainer in XmlDoc.Root.Descendants (schema + "EntityContainer"))
        {
			#>
				// Data source: <#= entityContainer.Attribute("Name").Value  #>
				<#

Practical example: although it was tempting to try to generate a WinForms application based on the client lsml, we found it more rewarding to use this in our reporting solution instead.  We have this one LightSwitch application which exposes a couple of views (BI sans BS).  Reports are ran from the server as well, using the ServerApplicationContext as a data source.  However, when an end-user wants to design a new, or alter an existing ‘report definition’, he/she can’t “access” the ServerApplicationContext in the end-user report designer.  As a workaround, we use T4 to generate a stand-alone class library with a simplified layout of our LightSwitch ServerApplicationContext, but which spits out random dummy data when accessed. This class library is then distributed alongside with an end-user report designer, so that they can design the reports.  When a report is uploaded, we simply swap out the ‘Dummy’ data source for one that accesses the ServerApplicationContext instead.  (Mega-Props to Paul Van Bladel for switching on the light here ;-) )

Here’s a fragment of the full T4 template, more likely to be used as an example than anything else.  As you can see, it generates a partial class, so that I can have some non-generated methods as well (like: CreateDummyData< T >).

The amount of LightSwitch and T4 resources online right now is … Well, just this post… Two: this post, and Paul Van Bladel’s material.  If you ever decide to wander on this lucrative T4+LightSwitch combination, please do share your LightSwitch love so that I and others can learn.

Keep rocking LS!

Jan