Volta Targets

Most of the time, developers will create one of two models: Volta applications or Volta controls. An application is a self-contained program that executes on its own; a control is a group of UI elements that can be reused in other programs.

Volta Applications

A Volta application is structured like a WinForms application, so is immediately familiar to millions of developers. The minimal Volta application comprises the following: 

  • A host page: analogous to the WinForms designer in the IDE, provides the visual elements displayed by the browser. All page elements accessed from code must have an id attribute. The host page may be in HTML, XAML, or other presentation formats.
  • Application classes: equivalent to Program.cs (bootstraps a WinForms application).
  • Bootstrap code: points the browser to the class implementing the top-level page.

This mirrors the structure of a WinForms application. In the examples below, we use HTML rather than Win32 for the UI library.

image002

VoltaPage1.Designer.cs specifies the stating page, and declares the InitializeComponent() method:

using Microsoft.LiveLabs.Volta;

 

[assembly: StartPage("Page.html")]

[assembly: VoltaFile("favicon.ico")]

 

namespace VoltaApplication1

{

    public partial class VoltaPage1

    {

        partial void InitializeComponent();

    }

}

The browser loads Page.html , which holds the HTML describing the user interface. The page is ordinary HTML, which may be authored in any fashion, such as with Visual Studio’s designer:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"

  "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

    <title>VoltaApplication1</title>

    <link rel="shortcut icon" href="/favicon.ico"/>

    <style type="text/css">

    </style>

</head>

<body>

</body>

</html>

Program.cs creates a new instance of the page class and opens the browser on it:

using System;

using Microsoft.LiveLabs.Volta.Html;

 

namespace VoltaApplication1

{

    class Program

    {

        static void Main(string[] args)

        {

            Browser.Load(new VoltaPage1());

        }

    }

}

VoltaPage1.cs contains the code that executes in the browser. The InitializeComponent() partial method provides a clean separation between the source code generated by the VSIP package and our code.

using System;

using Microsoft.LiveLabs.Volta.Html;

using Microsoft.LiveLabs.Volta.Xml;

 

namespace VoltaApplication1

{

    public partial class VoltaPage1 : Page

    {

        public VoltaPage1()

        {

            InitializeComponent();

        }

    }

}

Volta Controls

In WinForms programming, we can create custom controls to extend the large collection of existing, pre-supplied controls. The set of native controls supplied with HTML is smaller, so we are more likely to extend the collection with custom controls.

image003

Volta controls allow us to group several user interface elements and use them as one (the Composite design pattern). For example, the following figure shows a custom latitude-longitude Volta control.

Building Volta Controls

A Volta Control comprises a UI (defined in HTML) and functionality (defined in code). In Visual Studio we build controls using the Volta Control project template installed by the VSIP package.

image004

Anatomy of a Volta Control

A Volta control consists of the following:

image005

In the above diagram MyControl.html holds the HTML content, LocationControl.cs holds the functionality, and LocationControl.Designer.cs provides the name of the file holding the HTML.

  • HTML content: provides the visual elements of the control. Rather than complete HTML (as for a Volta application) the control’s HTML must be enclosed in a top-level div element. Volta scopes the element IDs within the control’s DIV. The HTML code for the latitude-longitude control follows.

 

<div>

 <table>

  <tr>

   <td>Latitude:</td>

   <td><input id="lat" type="text" style="height: 20px;" /></td>

  </tr>

  <tr>

   <td>Longitude:</td>

   <td><input id="lng" type="text" style="height: 20px;" /></td>

  </tr>

  <tr>

   <td colspan="2" align="right">

    <button id="latLngButton" style="height: 20px;">Lat/Lng Button</button>

   </td>

  </tr>

 </table>

</div>

  • Control classes: implement the behavior of the control. Typically the control class wires the DOM elements of interest to event handlers. Controls access DOM elements with the superclass’ GetChildById method rather than with the GetById we use in Volta applications. To maintain the scoping of the control elements the compiler mangles IDs so they won’t clash with the IDs of the control’s container.

public LocationControl(string buttonLabel)

    : base("MyControl.html")

{

    InitializeComponent();

 

    latLngButton.InnerText = buttonLabel;

    latLngButton.Click += LatLngButton_Click;

}

//

partial void InitializeComponent()

{

    latBox = (Input)GetChildById("lat");

    lngBox = (Input)GetChildById("lng");

    latLngButton = (Button)GetChildById("latLngButton");

}

Adding the Control to the DOM

Once we define the control we construct it and attach it as a regular HTML element, with AppendChild:

positionControl = new LocationControl("Go To");

positionControl.PositionChangedHandler += LatLngControl_PositionChanged;

positionControl.AppendChild(positionControl);

Control Error Handling

The Volta runtime detects errors that may appear when it loads controls. It signals these errors visually, through changing the rendering of the border around the control:

  • Dashed red border around the control: load failed
  • Solid red border around the control: error in the HTML, such as not finding the enclosing div element

Importing additional Files

Sometimes controls involve additional files, such as JavaScript libraries. You can accomplish this using the Import attribute targeted at the assembly. The following example includes the file ControlUtils.js in the control.

[assembly:ScriptReference("Volta\\ControlUtils.js")]