RSS

Category Archives: WPF

Introducing S# scripting language and runtime


Today we are very excited and proud to announce that we finished testing and moved to the packaging procedure for our next brainchild called “Orbifold S#“. The purpose of this article is to give a brief overview of what S# actually is, key features and possible use cases.

S# is a weakly-typed dynamic language and runtime infrastructure to make your applications extendable, customizable and highly flexible. It allows introducing expressions and large code blocks evaluation within your applications in the similar way Microsoft Office deals with VBScript, gives you possibilities providing rich formula evaluation capabilities like it can be seen in MS Excel, etc.

“Orbifold S# Runtime” will be distributed absolutely free for academic and non-commercial usage!. You can download runtime right now from here.

The key principles of S# are:

  • Be simple
  • Be efficient
  • Be intuitive

S# runtime has been designed to be easily hosted by applications. Minimum script execution scenario requires two lines of code! The important part of S# is its well-defined extendable runtime engine together with the application programming interface that allows full bi-directional communication between script and application code. In particular it is easy to extend S# by embedding external functions and functional objects, shared static or dynamic variables, operator handlings and type filters from the host application. Moreover the execution semantics of some language constructs has extensibility mechanisms available externally. This enables developers to create user-friendly executable business/domain specific languages on S# basis.

S# can work in single-expression mode in order to execute string expressions to values. This is especially helpful when application should allow users executing only light-weight portions of the functionality. S# is a pure .NET interpreted language completely written in C#.

For the moment it is ported to the following platforms:

  • Microsoft .NET 3.5 (SP1)
  • Microsoft Silverlight 3.0
  • Microsoft .NET Compact Framework
  • Microsoft XNA Framework
  • MONO

This means that S# runtime can be hosted by applications based on .NET like Console, Windows Forms, ASP.NET, Silverlight 2 and 3, Windows Presentation Foundation (WPF), XNA (both PC and XBox scenarios) and MONO (Linux).

Key features that will be dwelled on in the upcoming articles are:

  • Designed to be easily embedded into applications
  • Highly extensible grammar and language
  • Rich and controlled communication between runtime and host application in both directions
  • Sits on the top of .NET, has support for interaction with .NET code
  • Works in a single-expression evaluation mode to execute string expressions to values and return results to application
  • No code emitting, no CodeDom or background compilation, 100% interpreted language (own Virtual Machine and Debugging facilities are in progress)
  • Completely in-memory execution, does not require temp files, local system access, etc
  • C# and Java-like language syntax designed to be familiar to .NET and Java developers; easy to study for non-developer users
  • Various platforms are supported
  • Fully remotable; expressions and scripts can be sent across the wire and executed on a remote machine
  • Weakly-typed as IronPython and IronRuby for .NET

Installation Experience

You will need a couple of clicks in order to install S# runtime on your machine. For the moment runtime requires less than 1 MB on you hard drive.

SSharp_Installation_1

SSharp_Installation_2

SSharp_Installation_3

SSharp_Installation_4

For the moment you will have runtimes only for .NET 3.5 and Silverlight 3.0 installed by default. Both components are automatically registered within the “Add Reference” dialog in Visual Studio 2008 (note this requires installation to be started by a user with administrator account).

When creating a new Silverlight application you will be able adding S# reference without any additional implications related to finding the assembly installed on the local drive:

SSharp_Installation_VS

From Installation right to Execution

I am going to show you how easily you can start hosting S# runtime right after installation process is finished. You need to create an empty “Silverlight 3″ application project and add reference to “Orbifold S# for Silverlight” assembly using “Add Reference” dialog in Visual Studio 2008.

Next open “MainPage.xam” file and add a Canvas control. We are going to execute scripts that perform some operations against the Canvas element.

SSharp_Intro_1

After that you will need opening the code-behind file “MainPage.xaml.cs”. S# runtime hosting will require at least 2 namespaces involved: “Orbifold.SSharp” and “Orbifold.SSharp.Runtime”

SSharp_Intro_2

Note that S# runtime should be initialized before executing scripts. This procedure should be done once and I would recommend placing “RuntimeHost.Initialize()” method call somewhere in “App.xaml.cs” in the future.

Now it’s time to do some scripting on the “MainPage.Loaded” event:

SSharp_Intro_3

S# runtime supports a large amount of Scoping facilities (local scopes, global scopes, dynamic or application-controlled scopes). The same goes to execution contexts. Execution Contexts is a highly valuable and extensible area that deserves a separate article. All this will be  described in future articles and in API guides.

As I want promoting my “canvas” element to the runtime I need creating a simple execution context for my future script and provide possibility accessing “canvas” during runtime. This is achieved by adding a “canvas” variable to the scope that references our “canvas” element inside application. Note that you can provide any “alias” you want and it may not carry the same name as host-side variable/element.

Next step is defining the body of the script. I’m going to assign a new background brush for the Canvas and add a Rectangle element. Note that I don’t have to use full namespace paths for .NET classes as they are resolved automatically by S# runtime. You may forget about endless “using” clauses here.

After that I create a Rectanlge, configure it’s properties (including attached ones) and add it to the Children collection of the Canvas control by referencing “canvas” variable.

Finally I call “Script.RunCode” providing the body of the script and root execution context. When launching this Silverlight application you will see the following result:

SSharp_Intro_4

Yes, everything works perfect. Script got access to application structures and even managed to create and add new objects using core .NET Silverlight functionality. I would like to highlight “namespace resolving” feature once more as it really simplifies coding efforts. Let’s extend the script above to apply rotation for the Rectangle shape. “RotateTransform” class resides in “System.Windows.Media” namespace in Silverlight 3.0.

SSharp_Intro_5

As S# is a weakly-typed language you don’t have a need worrying about value types as they will be resolved automatically during runtime.

When running modified script you should see the following results:

SSharp_Intro_6

Extending Language with Custom Functions

Though S# supports a huge part of C# syntax constructions it may be required adding some domain-specific constructions or functions that simplify script building for end-users.

I am going to create two new functions: “CreateRectangle” that creates a Rectangle shape in a simplified manner and “Rotate” that will rotate FrameworkElement.

CreateRectangleFunction

SSharp_Ext_2

RotateElementFunction

SSharp_Ext_3

Both functions are fairly simple and don’t require comments. Please note that each S# function element should expose “IInvokable” interface. This is the only requirement for external functions integration.

In order to promote these functions you will need to include them into the scope the same fashion “Canvas” element was done – ScriptContext.SetItem() method. However to reduce development time there are also generics-based methods:

SSharp_Ext_1

Note that you can provide any name for the function. In this case I used “CreateRectangle” and “Rotate”. Now let’s modify the code from the samples above in order to consume new functions:

SSharp_Ext_4

This time the code becomes less complex but more efficient. I can create a Rectangle shape providing position and size and can call “Rotate” in order to apply Rotate Transformation.

Just for demonstration purposes I’ve added a function usage sample. I’ve introduced a function (event handler) called “OnCanvasClick” that is wired with “MouseLeftButtonDown” event of Canvas. Function requests access to global variable scope via the “global” keyword (similar to PHP)

SSharp_Ext_5

Now if you execute a script Rectangle will rotate 10 degrees each time you click design surface with a left button of the mouse. Another important point is that weakly-typed and dynamic nature of S# allows me accessing Angle value of RenderTransform property as of RotateTransform actually. By default RenderTransform property is of Transform type. S# didn’t require me doing type casting or conversion in order to set property value and this is really helpful in many scenarios.

The S# language has a great number of features and runtime is extremely extensible. We will unveil more details, links and samples for S# very soon.

UPDATE: Meanwhile we are finishing all the packaging work you can download the raw runtime (without documentation, samples and some other stuff) right now here.

 
4 Comments

Posted by on November 8, 2009 in .NET, Info, Silverlight, WPF

 

Tags: , ,

WPF PropertyGrid: Telerik WPF Controls 2009 Integration Kit


I’m glad to announce that we are going to include a “Telerik WPF Controls 2009” Integration Kit into every “Orbifold WPF PropertyGrid 2.0″ package. This is a quick start WPF project demonstrating how easily Telerik Controls 2009 can be used for property editing within the Orbifold PropertyGrid control. Getting started guide will also be upgraded to cover Telerik integration steps.

WPG 2.0 Fully Functional Demo

It should take less than an hour to reproduce the given project. The screenshots are given below.

Color Picker

WPG_Color_01

WPG_Color_02

Date and Time Pickers

WPG_DateTime_01

WPG_DateTime_02

WPG_DateTIme_03

Masked Editors (Date and Time)

WPG_Masked_01

Masked Editors (General)

WPG_Masked_02

Numeric Editors

WPG_Numeric_01

Hope you will enjoy this kit.

 
2 Comments

Posted by on May 21, 2009 in Info, WPF PropertyGrid

 

Tags: , , ,

First WPF Parallel Coordinates Control


I’m glad to announce that together with Francois Vanderseypen we’ve successfully introduced the first WPF Parallel Coordinates Control for a customer of ours! At least I could not find any one in the Google for the moment of writing this article ;)

“ParaGraph” is capable of displaying any types of data like strings, doubles, datetimes, etc. and can be easily bound to a DataTable instance. It has no problems visualizing CSV/Spreadsheet data bound to it. The control it is highly customizable and nearly every visual feature can be switched off/on as well as configured either via xaml and control templates or code behind settings.

The Demo Application demonstrating basic functionality can be found here

1. Overall look of the demo application:

 

image1-overall-look1

2. Support for Background Grid and Range labels:

image2-background-grid-and-range-labels3

3. Lines Highlighting and Tooltips

image3-line-highlighting-and-tooltips1

4. Histogram (Emphasizing the Accumulation Points)

image4-histogram1

5. Axes scaling (zooming in and out)

image5-axes-scaling1

By default control resides in “Swap” mode. You can drag each single Axis to a different location in order to change (swap) them immediately with redrawing of all corresponding data values. 

6. Line Thickness/Hover Thickness

image6-line-and-hover-thickness1

These are the key features I wanted to highlight but not the all amount ;)

For more details please refer also to the initial announcement here.

 
3 Comments

Posted by on March 20, 2009 in Diagramming, Info, WPF

 

Tags: , ,

Bringing MEF to Xaml via MarkupExtension


Nearly a year ago I was playing with Unity container in the scope of pure Xaml and Markup extensions. There was a 4-part series of articles on my old blog: 

Injecting Xaml with Unity Application Block using Markup Extensions. Part 4

This time I’ve decided to continue my extreme development and to try injecting UI controls into WPF layout directly from MEF :)

Note that this is an experimental stuff, I know about Prism/CompositeWPF and many other things. I was just intrested whether it is possible do it the way I did  ;)

1. Preparing Layout

I wanted to have something like the following:

<Window
  x:Class="XamlifiedMEF.Window1"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:local="clr-namespace:XamlifiedMEF"
  Title="Xamlified MEF" Height="600" Width="800">

  <StackPanel>
    <local:MefPart Contract="TextBoxPart"/>
    <ItemsControl ItemsSource="{local:MefPart Contract=ButtonPart}"/>
  </StackPanel>

</Window>

where the StackPanel element imports one TextBox (via the “TextBoxPart” contract) and additionally nests a single ItemsControl having an ItemsSource as a collection of exported Button elements (via the “ButtonPart” contract).

2. MEF Locator

As a common Xaml MarkupExtension cannot be imported or built up via some sort of ObjectBuilder (in order to get dependencies injected) you might need some static entry point (Service Locator). I recommend reading the article “CommonServiceLocator for MEF, a service is a service”  by Glenn Block or referring to codeplex version of CommonServiceLocator

In my case I simply decided to use the static class in order to get access to CompositionContainer:

namespace XamlifiedMEF
{
  internal static class Mef
  {
    private static readonly CompositionContainer _container;
    public static CompositionContainer Container
    {
      get { return _container; }
    }

    static Mef()
    {
      _container = new CompositionContainer(
        new AssemblyCatalog(
          Assembly.GetExecutingAssembly()));
    }
  }
}

 Of course in “real” implementations this service might require proper implementaiton and configuration but I left it simple for clarification purposes.

3. Parts

Next thing you will need is defining a couple of parts to be injected/imported into the layout. I’ve created a dummy textbox and three buttons:

namespace XamlifiedMEF
{
  [Export("TextBoxPart")]
  public class TextBoxPart : TextBox
  {
    public TextBoxPart()
    {
      this.Text = "Hi, I'm imported text part";
    }
  }

  [Export("ButtonPart")]
  public class Button1 : Button
  {
    public Button1()
    {
      this.Content = "I'm a button part 1";
    }
  }

  [Export("ButtonPart")]
  public class Button2 : Button
  {
    public Button2()
    {
      this.Content = "I'm a button part 2";
    }
  }

  [Export("ButtonPart")]
  public class Button3 : Button
  {
    public Button3()
    {
      this.Content = "I'm a button part 3";
    }
  }
}

The samples above are fairly simple and guess need no comments ;)

4. Markup Extension

And finally you will need a simple markup extension that will get one or several parts from the MEF container. Here’s the smallest extension that could be implemented in this case:

namespace XamlifiedMEF
{
  [MarkupExtensionReturnType(typeof(FrameworkElement))]
  public class MefPartExtension : MarkupExtension
  {
    [ConstructorArgument("Contract")]
    public string Contract { get; set; }

    public MefPartExtension()
    {
    }

    public MefPartExtension(string contract)
    {
      this.Contract = contract;
    }

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
      ExportCollection<FrameworkElement> exports =
        Mef.Container.GetExports<FrameworkElement>(Contract);

      if (exports.Count == 0) return null;
      if (exports.Count == 1) return exports[0].GetExportedObject();

      var items = from Export<FrameworkElement> item
                    in exports
                  select item.GetExportedObject();

      return items;
    }
  }
}

Note:  The extension is marked with FrameworkElement return type in case a single UI part is imported.

The core of the extension is “ProvideValue” method that should be always implemented. You will need to get the collection of exports by provided contract name. Next I determine whether ther resulting collection contains one element or several and return the values according to the result.

When you will launch the application you will see that all the declared elements were successfully imported into the layout. 

Demo project can be downloaded here…

 
2 Comments

Posted by on February 23, 2009 in WPF

 

Tags: , , ,

Using EventAggregator with MEF


Update (4/18/2010): I’ve created another sample covering Silverlight 4 scenario. Event Aggregator was successfully ported to Silverlight 4 and marked with ExportAttribute to be able importing it without additional implications. You can find sample here.

Recently I was seeking for a possibility making MEF parts to respond host application as well as neighbouring parts events in a weak way. Actually I was looking for some sort of Event Broker similar to that coming as a Unity Sample (Enterprise Library 4.x). For the moment MEF (MEF 4 preview) does not support importing and exporting events or multicast delegates so custom solutions are required in order to accomplish such task. From one side I didn’t want mixing MEF with Unity/ObjectBuilder in order to inject event publications/subscriptions. From the other side I didn’t want mixing MEF with Composite WPF (former Prism) though I like their awesome EventAggregator very much.

After analysing CompositeWPF sources I found out that EventAggregator is presented by a completely isolated part having no dependencies on the rest of the library. So it means that it can be easily used outside the assembly without any implications. This was something I needed very much.

Extracting EventAggregator into a separate assembly takes a couple of minutes assuming that you have downloaded the sources. Implementing a simple MEF-powered application also takes a couple of minutes. MEF project got a useful set of samples within their wiki. Sample application demonstrating the use of EventAggregator with MEF as long as the extracted EventAggregator code can be found at the end of this article…

Small walkthrough

I will show how a simple user message can be broadcasted by an application and processed by a control that was imported from a MEF Catalog and injected into the main application layout

1. Preparing a simple message event

First of all you need to define a message format that will be sent to external components. It can be defined by the following class:

  public class UserMessage
  {
    public string Text { get; set; }

    public UserMessage(string text)
    {
      this.Text = text;
    }
  }

Next you have to define an event body that external components will be subsribing to. Hosting application will also use it for raising a message event:

   public sealed class UserMessagePostedEvent
    : CompositePresentationEvent<UserMessage>
  {
  }

You don’t need providing additional memebers to this class as CompositePresentaionEvent<T> already contains everything needed.

2. Preparing a simple event consumer

Now you need to define a MEF part that will be consuming user message events raised by hosting application or neighbours. Let’s turn a standard WPF TextBox into a MEF part:

  [Export("EventViewer")]
  public class EventViewer : TextBox, INotifyImportSatisfaction
  {
    [Import]
    private IEventAggregator eventAggregator;

    private SubscriptionToken subscriptionToken;

    #region INotifyImportSatisfaction Members

    public void ImportCompleted()
    {
      if (eventAggregator != null)
      {
        UserMessagePostedEvent messagePostedEvent =
          eventAggregator.GetEvent<UserMessagePostedEvent>();

        if (subscriptionToken != null)
          messagePostedEvent.Unsubscribe(subscriptionToken);

        subscriptionToken = messagePostedEvent.Subscribe(
          OnUserMessagePosted,
          ThreadOption.UIThread,
          false);
      }
    }

    private void OnUserMessagePosted(UserMessage message)
    {
      this.Text += Environment.NewLine + message.Text;
    }

    #endregion
  }

Note that Textbox called EventViewer imports EventAggregator via its IEventAggregator interface. Next on ImportCompleted event it creates a subscription token for UserMessagePostedEvent you’ve created earlier. After that subcription is wired with OnUserMessagePosted handler that will add received message text to a TextBox text.

3. Preparing a Window layout

Now you need creating some debugging layout to ensure application can raise events and imported parts can handle and react on messages. Here’s the simple xaml for the testing window:


<Window
  x:Class="EventAggregatorForMEF.Window1"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  Title="EventAggregator for MEF" Height="600" Width="800">

  <Grid Name="LayoutRoot">
    <Grid.RowDefinitions>
      <RowDefinition Height="*"/>
      <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    <Button Name="SendMessage"
            Grid.Row="1"
            Content="Send message"
            Click="SendMessage_Click"
            MouseEnter="SendMessage_MouseEnter"
            MouseLeave="SendMessage_MouseLeave"
            />
  </Grid>

</Window>

Testing layout is represented by a standard WPF Grid panel. Panel consists of two rows. First row occupies the most of the free space (Height=”*”) and the second row takes the Height enough to display a “Send Message” button. First row in this case serves a placeholder for the control being imported from MEF catalog.

Additionally “Send Message” button will raise three events “Click”, “MouseEnter”, “MouseLeave” that will take part in the testing process.

4. Code behind

  public partial class Window1
    : Window, INotifyImportSatisfaction
  {
    CompositionContainer _container;
    IEventAggregator eventAggregator = new EventAggregator();

    [Import("EventViewer")]
    private TextBox viewer = null;

    public Window1()
    {
      InitializeComponent();
      Compose();
      this.Loaded += new RoutedEventHandler(Window1_Loaded);
    }

    private void Compose()
    {
      _container = new CompositionContainer(
        new AssemblyCatalog(Assembly.GetExecutingAssembly()));

      CompositionBatch batch = new CompositionBatch();
      batch.AddPart(this);
      batch.AddExportedObject<IEventAggregator>(eventAggregator);

      _container.Compose(batch);
    }

    void Window1_Loaded(object sender, RoutedEventArgs e)
    {
      PostUserMessage("Window loaded...");
    }

    #region INotifyImportSatisfaction Members

    public void ImportCompleted()
    {
      if (viewer != null)
      {
        this.LayoutRoot.Children.Insert(0, viewer);
        Grid.SetRow(viewer, 0);
      }
    }

    #endregion

    void ButtonClick(object sender, RoutedEventArgs e)
    {
      PostUserMessage("Button clicked...");
    }

    void ButtonMouseEnter(object sender, MouseEventArgs e)
    {
      PostUserMessage("Mouse entered button..");
    }

    void ButtonMouseLeave(object sender, MouseEventArgs e)
    {
      PostUserMessage("Mouse left button..");
    }

    void PostUserMessage(string text)
    {
      eventAggregator
        .GetEvent<UserMessagePostedEvent>()
        .Publish(new UserMessage(text));
    }
  }

First you initialize the CompositionContainer (for more details on CompositionContainer please refer the MEF’s Programming Guide). Also you insert EventAggregator into the container as an IEventAggregator export and declare a placeholder variable for importing an “EventViewer” external part (as a TextBox).

Upon InsertCompleted event the imported Event Viewer control is injected into the main window layout (first row that occupies most of the free space).

Finally I’ve declared three event handlers for the button control that raise a simple event by means of a helper method called PostUserMessage.

After running an application you will be able to see that external part successfully wires the EventAggregator events and is able processing messages send by external components.

WPF sample with EventAggregator assembly can be downloaded here

 
8 Comments

Posted by on February 21, 2009 in WPF

 

Tags: , , , ,

 
Follow

Get every new post delivered to your Inbox.

Join 71 other followers

%d bloggers like this: