Need a soft/virtual keyboard on your Silverlight application? Check this out Virtual Input Keyboard & Behaviours for Silverlight by Orktane. Thanks to the author’s tremendous effort, the fully functional soft keyboard is supported in both Silverlight 3 and Silverlight 4.
For the past two weeks, I developed a prototype of Kiosk application using Silverlight 4. As Siverlight 4 is just newly released, I believe by sharing my experience as following will benefit the others. Let’s have a look into a few screenshots of the Kiosk application:
Check out and view orders page:
Payment page which leads to printing of confirmation receipt:
That’s all! Looks simple, however the implementation is not so easy. Let’s go through the implementation process in Problem/Solution format:
Problem #1: Design…Design….Design
"I can’t design. I’ not talented. The crappy design tool doesn’t work like what I expected". If you got the same experience, welcome to my “I hate design” club.
Solution: You just have to live with it
You do not need great design skill in order to design UI of Silverlight application. The only tool you will use and play with is Expression Blend (provided you have all the necessary graphic elements). Download "Getting Started: Create Silverlight Experiences with Expression Blend 3 Course" provided by Microsoft. Study and go through the tutorial examples. I assure you that even a developer can design a great UI using Expression Blend :).
Problem #2: Storing data in Silverlight
"I need to store and retrieve data in my Silverlight application. What are the possible ways?". From my experience, you can either 1) use XML for simple data storing 2) use sql database, access database using WCF RIA service. In my prototype, I was leveraging on XML to store data, thus I will not cover the latter way in this post.
Solution: Design XML. Use LINQ to XML for CRUD in your Silverlight application Problem #3: Dealing with listbox
First, design your XML. XML is W3C standard. A lot of tutorials are out there to teach you how to design it. You can use Xmlreader/Xmlwriter to read/write XML, but my advise is to use LINQ to XML. Refer to this tutorial post on how to use LINQ to XML in Silverlight: "Using LINQ to XML in Silverlight 2" by Martin Mihaylov.
Adding and removing items into/from listbox control is fairly simple. It can be done by using listbox1.Items.Add() and listbox1.Items.Remove() command respectively in your code. However, this may not be the best way if the listbox holds custom listboxitem.
Solution: Data binding Problem #4: Passing data/information across pages
Data binding is the right way to go. In my prototype, the Order listbox is data bind with a class. Refer to DataBinding & DataTemplates Using Expression Blend for detailed implementation.
Passing data and information from initial page to the next page always appears to be a challenge to developers. There are a few ways to achieve it: 1) use static class 2) leverage on navigation framework, URI mapper and parameter 3) assign data/information to any parent page’s element tag and retrieve it from child page.
Solution: Choose the best fit Problem #5: Out of Browser (OOB)
In my prototype implementation, I use static class to store data and passing it across the page. For parameterized information, I assign it to the parent page’s contentframe tag (my Silverlight project template is navigation application) and retrieve the information from my child page. The reason I’m not using the navigation URI method is due to parameter value can only be retrieved in the OnNavigatedTo() event. Therefore, if you need the parameter value in constructor event to initiate the page, navigation URI method is not appropriate.
My prototype needs to be deployed locally without hosting it in a web server.
Solution: Understand OOB
Check out Silverlight 3 OutOfBrowser(OOB) behind the scenes Explained for detailed explanation of how OOB works and the way to package and deploy your xap locally. However, please keep in mind that the method only works for deploying Silverlight application which without elevated permission. Elevated permission is a new feature in Silverlight 4, in shorts, it needs to be stored in Isolated Storage folder in order to run in elevated permission mode.
"Is there any simple way to deploy Silverlight application? Probably to an exe file…like flash application?". YES! Desklighter provides us the tool to create standalone windows application from Silverlight XAP file. Just a few clicks and it works like a charm. Million thanks to Desklighter for saving my time from writing deployment instructions. Problem #6: Printing with non-windows driver printer
If you develop kiosk or POS application before, you probably know that the printer used by kiosk or POS application doesn’t have a window-based driver. Generally the printer we use is called OPOS, or I call it com-based printer.
Solution: COM Interop (only in Silverlight 4)
Consider upgrading your solution to Silverlight 4 because only Silverlight 4 provides COM Interop feature. First, you need to register (regsvr32) the DLL/OCX you intend to call from your Silverlight application. Next, use the code example as shown as here to refer and call the COM component. I will follow up with the implementation of COM interop with OPOS printer in the next post.
Undoubtfully, Silverlight 4 has created a big buzz among .Net developers recently. In this post, I’m sharing a cool demo site that is created by Sina.com. Basically it’s a stock monitoring site. By developing with Silverlight 4, the site (which is now a full-fledged Silverlight application) gives a wonderful experience to the users (both technical and non-technicaL). Check the site out and you will understand the excitement:
Oh yeah…first and foremost, install Silverlight 4 RC, available at http://bit.ly/ddN6gK.
After installation of Silverlight 2 RC, I found out that some of my Silverlight 1.0 applications are not working properly. A few searches show that there are few known issues:
Exceptions Reported instead of silent failures on Image URLs.
In Silverlight 1, if your application had a state where you were loading an image from an invalid URL it would fail silently, and no exception would be raised. Silverlight 2 raises an exception in this case, so if you wrote your code without an exception handler for this scenario, your end users would see a Silverlight error dialog if they are using Silverlight 2. Other than that, your application would behave in the same way (i.e. it would be unable to load the image from the invalid URL)
Action: Ensure that you are using exception handling before reading an image from a URL.
Change of behavior when Double Encoding Image URLs
Silverlight 1 was unable to handle some characters in Image URLs, and as such double encoding was necessary. This has been fixed in Silverlight 2, so if you have hard coded double-encoded URLs in your application, you may have some invalid URL errors thrown (see above)
Action: Remove any double-encoded hard coded URLs, and replace with normal URLs. Ensure that you are using exception handling before reading an image from a URL.
Change of behavior when reading XAML with relative path specifiers
This only applies when you specify the XAML on the Silverlight plug-in object. If you specified the XAML location using relative path specifiers (i.e. http://mydomain.com/app/../location.xaml), Silverlight 1.0 would resolve the URL. Silverlight 2 does not, and the full URL needs to be specified.
Action: Ensure that you are not using relative path specifiers on your XAML. Ensure that you are using exception handling on the plugin.
Exceptions Reported instead of silent failures on invalid XAML
When using createFromXAML to load XAML into your render tree at runtime, Silverlight 1.0 was forgiving of invalid XAML where you had a property at the root element of the XAML string that you are parsing. Silverlight 2 will throw and exception in this case.
Additionally XAML properties that were invalid would fail silently in Silverlight 1. If you had, for example, the following XAML: <TextBlock><Canvas.RenderTransform>…</Canvas.RenderTransform></TextBlock>
Silverlight 1.0 would be forgiving of this error, but Silverlight 2 will throw an exception.
Action: Ensure that you are using exception handling. If your XAML throws any exceptions due to these invalid properties you will need to fix your XAML.
Null reported instead of success on searching some XAML
When using findName() to find a XAML element, in Silverlight 1.0, in the case of a Storyboard, if you searched for a transform (example <Canvas.RenderTransform><ScaleTransform.ScaleX>), you would receive a positive result. However, this is inconsistent, and in Silverlight 2, you will receive ‘null’ as results of this search.
Action: Make sure your object is named and search for it by name instead of property path.
Exception on specific Text Wrapping property instead of silent failure
When using a TextBlock, Silverlight 1.0 mapped the ‘WrapWithOverflow’ setting to ‘Wrap’ on the TextWrapping property when it hit it, and as such this invalid property did not cause an exception. Silverlight 2 does not have this behavior, so the XAML will not parse and an exception will be thrown.
Action: Replace instances of the ‘WrapWithOverFlow’ setting with ‘Wrap’.
Line breaking differences on TextBlock
In some cases, a TextBlock would wrap text if not enough horizontal space was provided, despite the fact that it was not instructed to do so through property settings. This has been fixed in Silverlight 2, and as such you may see some places where your text is not wrapping where it did previously.
Action: If your TextBlocks look different with Silverlight 2 than they did with 1.0 this is the cause. You’ll need to edit your XAML to get the desired results.
Different handling of markers in an ASX file
In Silverlight 1, only markers that were within the duration specified in an ASX would be visible. In Silverlight 2, all markers are visible, so if you have an application that uses markers, and in particular pre-reads these markers, you may see some slightly different behavior.
Action: If you are pre-reading markers, and are receiving markers that are outside of your expected time range, you will need to truncate them manually.