Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Silverlight provides several methods for error handling, depending on the type of error. Errors are raised when the XAML parser hits a problem, loading isn’t completed properly, run-time errors are encountered, and when event handlers defined in the XAML document do not have a JavaScript function associated with them.
When initializing a control using the onError event handler, you specify a JavaScript function that will be called when an error occurs. However, if you do not specify one (or if you specify it as null), the default JavaScript event handler will fire.
.png)
Figure 5-1 Displaying control context.
The Default Event Handler
The JavaScript default event handler will display an error message alert box that contains basic details about the Silverlight error, including the error code and type as well as a message defining the specific problem and the method name that was called.
Following is an example of a badly formed XAML document, in which the closing tag of the TextBlock element is misnamed </TextBlok>:
<Canvas xmlns=https://schemas.microsoft.com/client/2007
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml">
<TextBlock>Hello, World!</TextBlok>
</Canvas>
If the error handler is set to null, then the default error handler will fire and display the default Silverlight error message, as shown in Figure 5-2.
.png)
Figure 5-2 The default error message.
Using Your Own Error Handler
You can use your own error handler by setting the onError property of the Silverlight control to a custom event handler function. Your error handler function will need to take two parameters: the sender object and the event arguments that define the specifics of the error that occurred.
There are three types of event argument that you can receive. The first is the basic
ErrorEventArgs object that contains the error message type and code. The errorType property defines the type of error as a string containing RuntimeError or ParserError. Based on this information, you can use one of the two associated derived error types.
When processing a parsing error in XAML, the ParserErrorEventArgs is available. This contains a number of properties:
- The charposition property contains the character position where the error occurred.
- The linenumber property contains the line where the error occurred.
- The xamlFile identifies the file in which the error occurred.
- The xmlAttribute identifies the xml attribute in which the error occurred.
- The xmlElement defines the element in which the error occurred.
Run-time errors are defined in the RuntimeErrorEventArgs object. This object also contains a number of properties:
- The charPosition property identifies the character position where the error occurred.
- The lineNumber property identifies the line in which the error occurred.
- The methodName identifies the method associated with the error.
In the previous section, you saw a parsing error as trapped by the default error handler. Here’s how you could capture the same error with your own error handler. First, you create the createSilverlight () method that sets up the error handler:
function createSilverlight()
{
Silverlight.createObject(
"Scene.xaml",
document.getElementById("firstControl"),
"agc1",
{
width:'300',
height:'300',
inplaceInstallPrompt:false,
background:'#D6D6D6',
isWindowless:'false',
framerate:'24',
version:'1.0'
},
{
<msl_b>onError:handleError,</msl_b>
onLoad:null
},
null);
}
Following is the HTML file that calls this revised Silverlight creation method and contains the handleError function that was defined as the error handler using the onError attribute:
<html>
<head>
<script type="text/javascript" src="Silverlight.js"></script>
<script type="text/javascript" src="createSilverlight.js"></script>
<script type="text/javascript">
function handleError(sender, errorArguments)
{
var strError = "Error Details: \n";
strError+= "Type: " + errorArguments.errorType + "\n";
strError+= "Message: " + errorArguments.errorMessage + "\n";
strError+= "Code: " + errorArguments.errorCode + "\n";
// We know (in this case) that its a parser error.
// For a more generic error handler
// you should trap on error type before calling
// properties on a specific argument type.
strError+= "Xaml File: " + errorArguments.xamlFile + "\n";
strError+= "Xaml Element: " + errorArguments.xmlElement + "\n";
strError+= "Xaml Attribute: " + errorArguments.xmlAttribute + "\n";
strError+= "Line: " + errorArguments.lineNumber + "\n";
strError+= "Position: " + errorArguments.charPosition + "\n";
alert(strError);
}
</script>
</head>
<body>
<div id="firstControl">
<script type="text/javascript">
createSilverlight();
</script>
</div>
</body>
</html>
When this is executed and the error is tripped, the alert box will display the contents of the error. Figure 5-3 shows an example of a customized alert box.
.png)
Figure 5-3 Using your own event handler.
Silverlight Control Properties
The Silverlight control has a number of properties, some of which were discussed in the section titled “Hosting Silverlight in the Browser.” In addition to being able to set them when you initialize the control, you can also set the controls properties using script. The control splits properties into three types: direct, content, and settings properties. Direct properties are properties of the control itself that are accessible using the control.propertyname syntax. Content properties and settings properties are accessed using the control.content.propertyname and con-trol.settings.propertyname syntax respectively.
Direct Properties
Following are the direct properties that are supported:
- initParams The initialization parameters that are passed to the control are stored in this property. It can only be set as part of the control initialization.
- isLoaded This property is true after the control is loaded; otherwise it is false. It is read-only.
- source This is the XAML content that you want to render. It can be a reference to a file, a URI to a service that generates XAML, or, when prefixed with a # character, it is a DIV containing XAML code in a script block.
Content Properties
When accessing content properties, you use the control.content.propertyname syntax. For example, if you want to access the actualHeight property, you use the control.content.actual-Height syntax. The following content properties are available:
- actualHeight This returns the height of the rendering area of the Silverlight control in pixels. The value returned depends on a number of different criteria. First, it depends on how the height of the control was initially set. Recall that it can be a percentage or an absolute pixel value. In the case of the former, the actualHeight property is the current height of the control, but if the user changes the browser dimensions, this will change. If the height was set using an absolute pixel value, this will be returned. When the control is used in full screen mode, this will return the current vertical resolution of the display.
- actualWidth This returns the width of the display. The value returned depends on a number of criteria and is similar to the actualHeight parameter.
- fullScreen This switches the Silverlight control display between embedded and full screen mode. It defaults to false, which is the embedded mode. When set to true, Silver-light will render to the full screen.
Settings Properties
The control also contains a number of properties that are defined as settings properties, where they are accessed using the control.settings.propertyname syntax:
- background This sets the background color of the Silverlight control. It can take several different formats, including a named color (such as Black), 8Bit Red/Green/Blue (RGB) values with or without alpha, and 16Bit RGB values with or without alpha.
- enableFrameRateCounter When set to true, Silverlight will render the current frame rate (in frames per second) in the browser’s status bar. It defaults to false.
- enableHtmlAccess When set to true, this will allow the XAML content to be accessible from the browser DOM. The default value is true.
- enableRedrawRegions When set to true, this shows the areas of the plug-in that are being redrawn upon each frame. It’s a useful tool to help you optimize your application. The default value is false.
- maxFrameRate This specifies the maximum frame rate to render it. It defaults to 24 and has an absolute maximum of 64.
- version This reports the version of the Silverlight control that is presently being used. It is a string containing up to four integers, separated by dots, which contain the major, minor, build, and revision number, though only the first two values (major and minor version number) are required.
- windowless This determines whether the property is displayed as a windowless or windowed control. When set to true, it is windowless, meaning the Silverlight content is effectively rendered “behind” the HTML content on the page.
Silverlight Control Methods
The Silverlight control has a number of methods that you can use to control its behavior and function. Similar to Silverlight property groups, the Silverlight methods are grouped into “families” of methods. At present, one direct and three content methods are supported. You’ll see which is which in the following sections, including samples showing their syntax and how to access them.
The createFromXaml Method
The createFromXaml method is a Silverlight content method that allows you to define XAML content to dynamically add to your Silverlight control. It takes two parameters. The first is a string containing the XAML that you want to use, and the other is the namescope parameter that, when true (it defaults to false), will create unique x:Name references within the provided XAML that will not conflict with any existing XAML element names.
There is a constraint around the XAML that you can add using createFromXaml. The XAML you add has to have a single root node. So, if you have a number of elements to add, make sure that they are all contained within a single containing Canvas element.
Additionally, createFromXaml does not add the XAML to the Silverlight control until it has been added to the children of one of the Canvas elements within the control. So, when you call createFromXaml, you get a reference to the node returned, and this reference is then used to add the node into the render tree. Following is an example:
function handleLoad(control, userContext, sender)
{
var xamlFragment = '<TextBlock Canvas.Top="60" Text="A new TextBlock" />';
textBlock = control.content.createFromXaml(xamlFragment);
sender.children.add(textBlock);
}
Here the XAML code for a text block control is created, containing the text “A new TextBlock”. This is then used to create an XAML node within the control content, and after it is complete, Silverlight will return a reference to the text block. This reference is then added to the Silver-light control’s render tree and is used to render the context of the text block.
The createFromXamlDownloader Method
The createFromXamlDownloader method is a content method used in conjunction with a Downloader object, which you will learn about later in this chapter. It takes two parameters. The first parameter is a reference to the Downloader object that downloads the XAML code, or a package containing the XAML code. The second parameter is the name of the specific part of the download content package to use. If this is a .zip file, then you specify the name of the file within the .zip file that contains the XAML code you want to use. When the downloaded content is not in a .zip package, then this parameter should be set to an empty string.
The createObject method
The createObject method is a direct method designed to allow you to create a disposable object for a specific function. In Silverlight 1.0, the only object that is supported is the Downloader object. We’ll cover this in greater detail later in this chapter.
The findName method
This content method allows you to search for a node within your XAML code based on its x:Name attribute. If findName finds a node with the provided name, it returns a reference to it; otherwise it returns null.
The Downloader Object
The Silverlight control provides an object that allows you to download additional elements using asynchronous downloading functionality. This allows you to download individual assets, or assets that are packaged in a .zip file.
Downloader Object Properties
The Downloader object supports the following properties:
- downloadProgress This property provides a normalized value (between 0 and 1) representing the percentage progress of the content downloaded, where 1 is equal to 100 percent complete.
- status This property gets the HTTP status code for the current status of the downloading process. It returns a standard HTTP status code, for example “404” for “Not Found” or “200” for “OK”.
- statusText This property gets the HTTP status text for the current status of the downloading process. This corresponds to the status code for the status property. For a successful request, the status will be “200,” and the statusText will be “OK.” For more information about HTTP status codes, check out the standard HTTP codes provided by W3C (https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html).
- uri This property contains the URI of the object that the downloader is presently accessing.
Downloader Object Methods
The Downloader object supports the following methods:
- abort This cancels the current download and resets all properties to their default state.
- getResponseText This returns a string representation of the downloaded data. It takes an optional parameter that is used to name the contents of the file name within a downloaded package.
- open This initializes the download session. It takes three parameters. The first is the verb for the action. The set of HTTP verbs is documented by the W3C; however, only the GET verb is supported in Silverlight 1.0. The second parameter is the URI for the resource that is to be downloaded. The optional third parameter determines if the download is synchronous or asynchronous. It defaults to true (for asynchronous download).
- send This executes the download request that was initialized with the Open command.
Downloader Object Events
The Downloader object supports the following events:
- completed This event will fire when the download is complete. It takes two parameters. The first is the object that raised the event (in this case, the downloader control itself), and the second is a set of event arguments (eventArgs). In Silverlight 1.0, the eventArgs parameter is always null.
- downloadProgressChanged This event will fire while content is being downloaded. It fires every time the progress (which is a value between 0 and 1) changes by 0.05 (5 percent) or more, as well as when it reaches 1.0 (100 percent). When it reaches 1.0, the completed event will also fire.
Using the Downloader Object
You create a Downloader object using the createObject method provided by the Silverlight control. Here’s an example:
<script type="text/javascript">
function handleLoad(control, userContext, sender)
{
var downloader = control.createObject("downloader");
}
</script>
The next step is to initialize the download session by using the Downloader object’s open method to declare the URI of the file, and then to call the send method to kick off the download. Following is an example that will download a movie file called movie.wmv:
function handleLoad(control, userContext, sender)
{
var downloader = control.createObject("downloader");
downloader.open("GET","movie.wmv",true);
downloader.send();
}
In order to trap the download progress and completion, you’ll need to wire the appropriate event handlers. Following is the same function, updated accordingly:
function handleLoad(control, userContext, sender)
{
var downloader = control.createObject("downloader");
downloader.addEventListener("downloadProgressChanged","handleDLProgress");
downloader.addEventListener("completed","handleDLComplete");
downloader.open("GET","movie.wmv",true);
downloader.send();
}
Now you can implement these event handlers. In this example, the DownloadProgressChanged event is wired to a JavaScript function called handleDLProgress, and the Completed event is wired to the handleDLComplete JavaScript function. You can see these functions here:
function handleDLProgress(sender, args)
{
var ctrl = sender.getHost();
var t1 = ctrl.content.findName("txt1");
var v = sender.downloadProgress * 100;
t1.Text = v + "%";
}
function handleDLComplete(sender, args)
{
alert("Download complete");
}