Skip to main content Skip to footer

Migrating from XAML to HTML5 with Wijmo

Many companies are starting to move their applications from Silverlight to HTML5 in order to target mobile users, and to remove dependencies on legacy technologies like Silverlight and browser plugins in general. If you’re working on a project of that nature, you should consider using Wijmo 5 as part of the migration process.

Migrate from Silverlight to HTML

Wijmo 5 helps you cut development time with a rich suite of business-oriented controls ranging from must-haves like Grids, Dropdowns and Menus, to advanced data visualization controls such as Charts and Gauges. Wijmo 5 controls have objects models that closely resemble those of Silverlight controls. And in addition to controls, Wijmo 5 provides a CollectionView class that makes migrating Silverlight applications even easier, and first-class support for AngularJS, which provides the MVVM support that is the cornerstone of virtually every XAML application. To demonstrate how easy Wijmo makes the migration process from Silverlight to HTML, we ported a sample Silverlight application created by Microsoft. The sample is called "Data Services Quickstart Sample". You can find it here: http://samples.msdn.microsoft.com/Silverlight/SampleBrowser/#/?sref=DataServicesQuickStart

The sample loads data from an OData source and allows users to select a customer from a ComboBox. Once a customer is selected, the sample allows users to select an order from a second ComboBox, and displays the order details on a grid and on some input controls. Here's what the Silverlight application looks like:

Like most XAML applications, the sample is implemented using the MVVM architecture. The ViewModel is straightforward: it loads the customer list into a CollectionView, updates the order list when the current customer changes, and updates the order details when the current order changes. The order and order detail lists are also implemented as CollectionView classes.

Wijmo CollectionView Makes Translation to JavaScript Easy

Because the ViewModel is based on the ICollectionView interface, translating it to JavaScript is incredibly easy if you use Wijmo’s CollectionView class. Here's the JavaScript version of the ViewModel written as an AngularJS controller:

// declare app controller
 app.controller('appCtrl', function appCtrl($scope) {

   // URL to Northwind service
   var svcUrl = 'http://services.odata.org/Northwind/Northwind.svc';

   // create customers, orders, details view
   $scope.customers = new wijmo.collections.CollectionView();
   $scope.orders = new wijmo.collections.CollectionView();
   $scope.details = new wijmo.collections.CollectionView();

   // when the current customer changes, get his orders
   $scope.customers.currentChanged.addHandler(function () {
     $scope.orders.sourceCollection = [];
     $scope.details.sourceCollection = [];
     var customer = $scope.customers.currentItem;
     if (customer) {
       loadData(svcUrl, $scope.orders,
         'Customers('' + customer.CustomerID + '')/Orders', {
         OrderDate: wijmo.DataType.Date,
         RequiredDate: wijmo.DataType.Date,
         ShippedDate: wijmo.DataType.Date,
         Freight: wijmo.DataType.Number
       });
     }
   });

   // when the current order changes, get the order details
   $scope.orders.currentChanged.addHandler(function () {
     $scope.details.sourceCollection = [];
     var order = $scope.orders.currentItem;
     if (order) {
       loadData(svcUrl, $scope.details,
         'Orders(' + order.OrderID + ')/Order_Details', {
         UnitPrice: wijmo.DataType.Number
       });
     }
   });

   // handle clicks on the Start button
   $scope.startButton_Click = function () {
     loadData(svcUrl, $scope.customers, 'Customers');
   }

 });

In case you're not familiar with AngularJS, it's worth pointing out that the $scope variable is Angular’s version of Silverlight’s DataContext variable. Notice how the customers, orders, and detail lists are also implemented as CollectionView objects. The “customers.currentChanged” event is used to load orders when the current customer changes. Similarly, the “orders.currentChanged” event is used to load order details when the current order changes. Now that we have the ViewModel (AKA controller) done, let’s look at the View. The original sample implements the view with this XAML (we removed some formatting-related markup to improve clarity):

<StackPanel DataContext="{Binding customersViewSource}">

   <!-- start button and Customer combobox -->
   <StackPanel>
     <Button Content="Start" Click="startButton_Click"/>
     <sdk:Label Content="Customers:" />
     <ComboBox
       ItemsSource="{Binding Source=customersViewSource}"
       DisplayMemberPath="CompanyName">
     </ComboBox>
   </StackPanel>

   <!-- select order for current customer -->
   <Border>
     <Grid DataContext="{Binding customersOrdersViewSource}">
       <sdk:Label Content="Order ID:" />
       <ComboBox
         ItemsSource="{Binding}"
         DisplayMemberPath="OrderID"
         SelectionChanged="orderIDComboBox_SelectionChanged">
       </ComboBox>
       <sdk:Label Content="Order Date:" />
       <TextBox Text="{Binding Path=OrderDate}" />
       <sdk:Label Content="Freight:" />
       <TextBox Text="{Binding Path=Freight}"/>
       <sdk:Label Content="Shipped Date:" />
       <TextBox Text="{Binding Path=ShippedDate}" />
     </Grid>
   </Border>

   <!-- grid with order details -->
   <sdk:DataGrid
     AutoGenerateColumns="False"
     ItemsSource="{Binding Source={customersOrdersOrder}" >
     <sdk:DataGrid.Columns>
       <sdk:DataGridTextColumn
         Binding="{Binding Path=ProductID}" Header="Product ID" Width="80*"/>
       <sdk:DataGridTextColumn
         Binding="{Binding Path=Quantity}" Header="Quantity" Width="60*"/>
       <sdk:DataGridTextColumn
         Binding="{Binding Path=Discount}" Header="Discount" Width="60*"/>
       <sdk:DataGridTextColumn
         Binding="{Binding Path=UnitPrice}" Header="Cost/Unit" Width="60*"/>
     </sdk:DataGrid.Columns>
   </sdk:DataGrid>
 </StackPanel>

Now look at the HTML5 implementation of the same view using Wijmo 5 and AngularJS directives:

<!-- start button and Customer combobox -->
 <dl>
   <dt></dt>
   <dd>
     <button type="button"ng-click="startButton_Click()">
       Start
     </button>
   </dd>
   <dt>OrderID:</dt>
   <dd>
     <wj-combo-box items-source="orders" display-member-path="OrderID" />
   </dd>
   <dt>Freight:</dt>
   <dd>
     <wj-input-number value="orders.currentItem.Freight" format="c2" />
   </dd>
 </dl>

 <!-- select order for current customer -->
 <dl>
   <dt>Customer:</dt>
   <dd>
     <wj-combo-box items-source="customers" display-member-path="CompanyName" />
   </dd>
   <dt>Order Date:</dt>
   <dd>
     <wj-input-date value="orders.currentItem.OrderDate" />
   </dd>
   <dt>Shipped Date:</dt>
   <dd>
     <wj-input-date value="orders.currentItem.ShippedDate" />
   </dd>
 </dl>

 <!-- grid with order details -->
 <wj-flex-grid items-source="details">
   <wj-flex-grid-column
     binding="ProductID" header="Product ID" width="80*" />
   <wj-flex-grid-column
     binding="Quantity" header="Quantity" width="60*" />
   <wj-flex-grid-column
     binding="Discount" header="Discount" width="60*" format="p0" />
   <wj-flex-grid-column
     binding="UnitPrice" header="Cost/Unit" width="60*" format="c2" />
 </wj-flex-grid>

The markup is actually simpler, but very similar. The “wj-combo-box” directive represents a ComboBox, and it has the same itemsSource and displayMemberPath properties as the XAML ComboBox. The “wj-input-number” and “wj-input-date” directives are used to implement number and date fields, and are much more functional than the plain text fields used in the original sample. Finally, the “wj-flex-grid” directive implements a data-bound FlexGrid that replaces the original “sdk:DataGrid”, complete with an itemsSource property and child elements that define the grid columns and their properties, including their bindings, headers, format string, and even to star-based sizing. Because Wijmo’s CollectionView and controls are based on the same concepts and have virtually identical object models to their XAML counterparts, the conversion to HTML and JavaScript can be done very quickly. This sample was ported in less than an hour.

Converting from Silverlight to HTML Improves Your Apps

But converting quickly is only part of the story. The most important thing is that the new version of the app is actually better than the original, because:

  • It runs on any device, including tables and telephones (Wijmo has great touch support)
  • It uses Bootstrap CSS to provide an adaptive layout, so the app looks great and remains functional on small screens, in portrait and landscape modes.
  • It is more robust and easier to use thanks to the specialized input controls.
  • It is only 15% the size of the original (160k vs over 1MB), so it loads quickly and starts much faster.

Here's a screenshot of the HTML version of the sample:

Bernardo de Castilho

comments powered by Disqus