Dynamic Silverlight Forms. Embedding S# Scripts into Xaml.

I’ve been receiving a lot of questions regarding the possibility of usage S# in a declarative way directly from xaml rather than from code behind. Such approach is extremely valuable when dealing with BPM-like usages and dynamic forms that are presented by raw Xaml stored in database and instantiated via XamlReader.

In this article I’m going to show you how easy it can be to embed a S# script into Xaml and execute it dynamically. For this purpose I will be using some blocks of the new upcoming “S# Silverlight Toolkit” that will be available soon as a part of the S# package. The toolkit will be distributed as a free addition with source code provided.

For the sake of simplicity I’m going to show the very basic injection of S# scripts into Xaml markup. I will be using Silverlight 3 for this purpose. The sample code will be updated to Silverlight 4 as soon as S# 2.0 reaches RTM.

1. Required Assembly References

You will need adding references to the following assemblies:

  • Orbifold.SSharp.dll
  • Orbifold.SSharp.Silverlight.Toolkit.dll (you can find it in the form of source code within the sample solution attached at the end of the article)

2. Required Namespace Declaration

You will need to declare 3 additional namespaces

  • sys” pointing to the “System” namespace in “mscorlib” to be able using basic .NET types from within Xaml;
  • scriptingRuntime” pointing to the “Orbifold.SSharp.Runtime” namespace to be able using “ScriptContext” from within Xaml;
  • scriptingToolkit” pointing to the “Orbifold.SSharp.Silverlight” namespace to be able using Silverlight facilities like “CodeBlock” and “ScriptManager” from within Xaml;

image

3. Introducing Script Execution Context for the Form

Obviously you will want providing some context variables or custom functions for the scripts executed by the form. For this purpose I’m declaring a ScriptContext instance in the resources section of the form:

image

Here’s the code behind I’ve used to initialize default script context for the form:

image

First of all you will need initializing Runtime Host. I’ve promoted the entire “System.Windows” assembly (via MessageBox type) to be able calling Message Boxes from within scripts.

Next I’ve got access to “defaultContext” declared in the markup and created a script variable “Form” pointing to the instance of this very Silverlight form. Additionally you may need assigning “ExecutionContext” attached property for the form if you want embedding scripts for the form-level events like “Loaded”.

4. Attaching S# Scripts to the UI elements

S# Silverlight Toolkit provides a set of facilities regarding script injection. You will need 2 of them for now: Code Block and Script Manager. CodeBlock class serves as a wrapper around plain S# script while Script Manager provides a set of attached properties (see Ramora Pattern) to wire UI elements with the S# runtime engine.

OnLoaded Attached Property

Allows you to associate a S# script with a FrameworkElement and execute it each time “FrameworkElement.Loaded” event is fired. Here’s a basic example:

image

ScriptManager.OnLoaded attached property setter accepts “CodeBlock” instance as a valid value. Every Code Block can contain a body of the S# script and can be optionally bound to the execution context.

The script above uses common Silverlight FrameworkElement.FindName method to find an element called “TextBox” and assigns its Text property to “Dynamically populated text!!!”.

ScriptManager.OnButtonClick attached property setter accepts “CodeBlock” instance as a value and wires a S# script with a “Button.Click” event:

image

Sample above shows a simple scenario of finding a TextBox element on the form and modifying its “Text” property.

ScriptManager.OnGotFocus attached property setter accepts “CodeBlock” instance as a value and wires a S# script with “UIElement.GotFocus” event:

image

5. Running Sample

After launching the sample you will see the following UI elements:

image

There is a Button and a TextBox controls. The text box will contain some text assigned by the Form-level script (ScriptManager.OnLoaded)

When clicking (and so focusing) the TextBox the “OnGotFocus” script will be executed:

image

When clicking a Button element the message box will appear and the TextBox.Text will be changed according to the “OnButtonClick” script:

image

image

Conclusion

The S# Silverlight Toolkit opens the door for more efficient and rich scripting for your applications. Being similar to ASP.NET development it provides facilities for dynamic invocation of your scripts during the UI life cycle, allows you storing the xaml in databases and instantiate the entire UI with corresponding scripts during runtime by means of XamlReader (note that all attached properties will be restored during form instantiation, and all event handlers will be re-assigned during XamlReader.Load process).

You can get the source code for this article here:

S# 2.0 features. It’s all about performance, dynamics and integration.

In this article I would like to give you some details towards next version (2.0) of the S# language and scripting runtime.

Version 2.x will be based on .NET 4.0 and will be supported separately of Version 1.x that is still built on the top of .NET 3.5. Both versions will have a set of common features powered by both .NET 3.5 and .NET 4.0 however version 2.x will introduce a set of brand new capabilities built on the top of .NET 4.0 only. The entire 2.x family will be backward compatible. There will be no breaking changes in the scripts and migration difficulties.

Performance

A lot of work is related to script execution performance. S# runtime is used in various reporting and visualization tools where execution time of large or repetitive blocks is very important. Version 2 provides tremendous improvements and optimizations in comparison to Version 1.0.

Here’s one of our comparison benchmarks for basic loops (execution results are given in milliseconds)

Script v.1 v.2 %
for (i = 0; i <= 100000; i++) { } 48.7 26.7 182
for (i = 0; i <= 100000; i = i + 1) { } 63.84 41.38 154
for (i = 0; i <= 100000; i++) {  i.ToString(); } 4129.5 227.06 1517
a = [1,2,3]; x = 0; for (i = 0; i < 100000; i++) { x = a[1]; } 1571.1 72.62 2164
a = [1,2,3]; for (i = 0; i < 100000; i++) { a[0] = i; } 2630.9 87.38 3011
x = null; p = new Person(); for (i = 0; i < 100000; i++) { x = p["testme"]; } 1242.8 75.56 1645
x = null; p = new Person(); for (i = 0; i < 100000; i++) { p["name"] = "test"; } 1322.8 82.2 1609
for (i = 0; i <= 100000; i++) { i.ToString(null); } 3257.8 773.06 421.4

As you can see the performance improvements for loops, method calls and array manipulations range from 200% for 3000% and this is not the complete list.

Here’s the graphical charts for the first 50 calls of each script benchmark (vertical axis is given in milliseconds):

image

image

image

image

image

image

image

image

All the tests were performed on Windows 7 Ultimate ( x64), Intel Core 2 Duo T9400, 2.5GHz, 4GB RAM

Dynamics

I’m glad to announce that S# 2.0 will support “dynamic” objects powered by .NET 4.0 and its DLR (Dynamic Language Runtime) part. There will be a new type alias called “dynamic” that will allow you creating objects on the fly similar to the following sample:

person = new dynamic();
person.Name = “John Doe”;
person.Age = 40;

This should significantly improve scripting experience an reduce efforts required to perform complex reporting or visualization scripts as types can be created dynamically during script execution instead of creating custom types and registering them within the runtime host.

The performance of dynamic objects is also very important for us. For the moment object property access (both getting and setting property value) is much quicker than of plain CLR type:

image

 

Integration

You will get more samples related to S# integration with other technologies and products. Soon there will be a set of articles regarding new features in S# for WPF and Silverlight, Microsoft Office 2007/2010 etc.

S# framework will provide a new libraries targeting OpenXml SDK 2.0 reuse within the scripts. It will be possible getting and setting data for Microsoft Excel 2010 document by accessing cells in scripts similar to the following way:

workbook = new Workbook(“Book1.xslx”);
workbook.Sheet1.A1 = “Hello world”;
workbook.Sheet1.A2 = 100;
workbook.Sheet1.B1 = workbook.Sheet1.A2 + 200;

More news are on the way…

S# 1.3 is out with .NET Compact Framework 3.5 support

I would like to announce that tomorrow we are releasing an updated version of S# Scripting Runtime (version 1.3) containing a set of bug fixes, performance and API enhancements and .NET CF 3.5 support.

Please refer to the official product page for getting more details and latest installation package.

Starting from now you will be able enriching your mobile software with rich capabilities of S# scripting. Here’s a couple of screenshots:

image

S# allows you creating content dynamically on the fly and that should be extremely valuable in various scenarios:

image

Execution of the script above will create a new Form with a TextBox control on it:

image

The sample above requires only 3 lines of code

image

Also we’ve updated the setup package to simplify your development efforts. The corresponding assembly will be automatically displayed within the “Add reference” dialog in Visual Studio:

image

Please refer to the official product page for getting more details and latest installation package.

Any feedback, suggestions or ideas are much appreciated.

Happy coding!