User:anonymousLog inRegister
Recents:
Silverlight Hello World User Control

Below is a sample User Control made with Silverlight Beta 1.0. But first, we will explain some Silverlight concepts.

Silverlight

Consider a standard Silverlight control (non GeneXus). Typically, we will find the following files:

  • silverlight.js
  • archivo.xaml
  • sample.htm

Silverlight.js is a standard .js file of the SDK.

Archivo.xaml contains a sketch of the page and, for example, a WPF subset can be used:

<Canvas
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

<Ellipse
Height="200" Width="200"
Stroke="Black" StrokeThickness="10" Fill="SlateBlue" />
</Canvas>

Sample.html will perform mainly two actions:  First, it will create a DIV that will host the control. Next, it will call a silverlight.js function (by passing it certain parameters) which is the one that will return the silverlight control code (that will be hosted in the previous DIV).

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>A Sample HTML page</title>
<script type="text/javascript" src="Silverlight.js"></script>
<script type="text/javascript" src="createSilverlight.js"></script>
<script type="text/javascript" src="my-script.js"></script>
</head>
<body>

<!-- Where the Silverlight control will go-->
<div id="mySilverlightControlHost">
</div>
<script type="text/javascript">

// Retrieve the div element you created in the previous step.
var parentElement = document.getElementById("mySilverlightControlHost");

Sys.Silverlight.createObject(
"archivo.xaml", // Source property value.
parentElement, // DOM reference to hosting DIV tag.
"mySilverlightControl", // Unique control ID value.
{ // Control properties.
width:'300', // Width of rectangular region of
// control in pixels.
height:'300', // Height of rectangular region of
// control in pixels.
inplaceInstallPrompt:false, // Determines whether to display
// in-place install prompt if
// invalid version detected.
background:'#D6D6D6', // Background color of control.
isWindowless:'false', // Determines whether to display control
// in Windowless mode.
framerate:'24', // MaxFrameRate property value.
version:'0.9' // Control version to use.
},
{
onError:null, // OnError property value --
// event handler function name.
onLoad:null // OnLoad property value --
// event handler function name.
},
null);
</ script>

</body>
</html>

It’s worth pointing out that from the xaml, object events are defined that are used in the sketch (ellipse, textblocks, storyboards, brushes, etc.) and are handled by javascript functions. For example:

<Canvas Width="300" Height="300"
xmlns="
http://schemas.microsoft.com/client/2007"
xmlns:x="
http://schemas.microsoft.com/winfx/2006/xaml"
Background="Transparent"
MouseLeftButtonDown="changecolor">
<TextBlock Text="click me" FontSize="50"/>
</Canvas>
function changecolor(sender, args) {
sender.background = "red";

alert("Height is " + sender.Height);
}

In the previous case, changeColor is a global javascript function.

Embedding a Silverlight Control in a GeneXus User Control

When a GeneXus user control is created, standard sources create a class instance of our control. This class contains all the information received from GeneXus: data bound properties, non data bound properties, and so on. So far so good.

When events are picked up from the xaml, in the previous example they are handled by global functions. In our case, however, we want these events to be handled by our class methods (our control), since only in the class scope we have access to the properties and events defined in the server.  Another solution could be devised but we’d have to keep references to our control, which seems more complicated when there are many controls.

Problem Definition 

In sum, the problem is as follows:

  1. xaml events have to be handled by methods accessing the properties and events.
  2. we have to initialize the xaml element properties (color ellipse, for example) with the properties we receive from GeneXus.

Solution

One possible solution is to create Silverlight objects dynamically from the javascript using the createFromXaml method.  For example:

<Canvas Width="300" Height="300"
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Background="Transparent"
MouseLeftButtonDown="createEllipse">

<TextBlock Text="click for circle" FontSize="40"/>
</Canvas>

function createEllipse(sender, args) {

var slControl = sender.getHost();
var e =
slControl.content.createFromXaml(
'<Ellipse Height="200" Width="200" Fill="Blue"/>');
var canvas = sender;
canvas.children.Add(e);
}

The idea is to concatenate the values received from GeneXus in the xaml that is passed to the createFromXaml function.

Another possible solution (which seems to be easier to handle), is to use the Load event of the Silverlight control to solve both problems, that is, to subscribe to the control events and to pass the properties to the control. The LOAD event will be handled by a class method of our user control. Thus, we will have access to all the properties and methods of the GeneXus user control. For example:

<Canvas Height="300" Width="300"
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Background="transparent">

<TextBlock x:Name="myTextblock" Text="hello world" FontSize="50">
<TextBlock.Foreground>
<SolidColorBrush x:Name="myTextblockBrush" Color="Black"/>
</TextBlock.Foreground>
</TextBlock>


<Ellipse x:Name="myEllipse"
Height="200" Width="200"
Canvas.Left="30" Canvas.Top="80"
Stroke="Black" StrokeThickness="10" Fill="LightBlue" />
</Canvas>

function HelloWorld()
{
this.Width;
this.Height;
this.FontFace;
this.FontColor;
this.FontSize;

this.show = function()
{
///UserCodeRegionStart:[show] (do not remove this comment.)
this.createMySilverlightControl();
///UserCodeRegionEnd: (do not remove this comment.)
}

this.createMySilverlightControl = function()
{

var imgsDir = gx.staticDirectory;
Sys.Silverlight.createObjectEx({
source: gx.util.resourceUrl(imgsDir + 'SilverlightHelloWorld/helloworld.xaml', true),
parentElement: this.getContainerControl(),
id: this.containerName + "Silverlight",
properties: {
width: this.Width,
height: this.Height,
framerate:'24',
version: "0.9"
},
events: {
onLoad: Sys.Silverlight.createDelegate(this, this.handleLoad)
}
});
}

this.handleLoad = function(control, userContext, rootElement)
{
//myEllipse
rootElement.findName("myEllipse").addEventListener("MouseEnter", Sys.Silverlight.createDelegate(this, this.MyEllipseMouseEnter));
rootElement.findName("myEllipse").addEventListener("MouseLeave", Sys.Silverlight.createDelegate(this, this.MyEllipseMouseLeave));
//myTextblock
rootElement.findName("myTextblock").FontSize = this.FontSize;
rootElement.findName("myTextblock").FontFamily = this.FontFace;
rootElement.findName("myTextblockBrush").Color = this.FontColor;
}

this.MyEllipseMouseEnter = function(sender, args)
{
sender.findName("myEllipse").fill = "red";

}

this.MyEllipseMouseLeave = function(sender, args)
{
sender.findName("myEllipse").fill = "LightBlue";

}

}

Sys.Silverlight.createDelegate = function(instance, method) {
return function() {return method.apply(instance, arguments);}
}

We can see how the handleLoad method is subscribed to the events and how properties are assigned. Note also that the createObjectEx function is passed this.getContainerControl() as parent, so it won't be necessary to do a this.setHtml.

Sample

Silverlight Hello World can be downloaded here. Basically, it prints a Hello World message using the font, size and color received from GeneXus, and draws an ellipse that changes color on MouseEnter/MouseLeave.




Created: 08/24/07 11:18 AM by gcuinas Last update: 04/05/10 06:33 PM by armando
 
Page
Categories
Group
Powered by GXwiki 3.0 (generated with GeneXus X Evolution 1 U1) gxwiki@gxtechnical.com