Monday, October 29, 2007

Disclosure

so for starters I don't consider my self a 'hacker' in the common sence of the term. I certainly don't go 'hacking' other people's computers. When I say 'Hacking' Silverlight, I don't approve of anything that is not strictly moral or ethical

and

what I do mean,

more or less,
when working with big silverlight projects,
that at times,

it fills like 'hacking' some of the things we have todo to get things working.

So I don't mean to sanction anything illicite. and 'HackingSilverlight' just sounds cool.

I have this sample on my blog about wiring Silverlight into the browser history. This is an old flash trick and it works pretty good. But from my perspective as a dicplined programmer it is totally a hack. Not that it should not be done or anything its just as a professional we try so hard to do things the right way or the fastest way in the best way possible and are so proud of our cool algorythm or application and take pride in the attention to detail that we tend to be abit agast at solutions like this.

so thats why I say 'HackingSilverlight'.

JavaScript type casting

here is one... So I'm doing some silverlight and I try to add two 'numbers' right. Javascript is supposed to be not strongly typed language but there are cases where you need to type caste... which normally only shows up in real languages or um strongly typed langauges like say C#. In JavaScript 'type casting' is a bit mucked up but basically there are two types you can try to force things to 'string' or 'number'. The code looks something like this:

var SomeValue = "100";
var SomeNumber = 3;

// alert 1: "1003"
alert( SomeValue + SomeNumber);

// alert 2: "103"
alert( Number(SomeValue) + SomeNumber);

So this is where we can get a way with telling people 1 * 1 may not always equal 2... in this sample the first alert is going to make everything a string where as in the next one we cast the questionable value to a Number and now the math works right...

hmmm... whats the point of a varient if it can't figure out its a number.

Anyway so there is type casting in JavaScript

Friday, October 26, 2007

Silverlight Key Events In full screen mode...

Jared my friend is building this video player in silverlight. Nothing new about that :) but I showed me its full screen mode and how he used the key up event from the esc to fix up his UI as he couldn't capture key events from silverlight from full screen mode... cool little hack persay. another way around that is to capture events off the document object and or if you can use the on full screen change event.

Embedding Popfly Silverlight Mashups in Community Server

Simons article on embeding Popfly silverlight in community server pretty much sums it up. Basically you have to enable iframes.

http://simonguest.com/blogs/smguest/archive/2007/05/23/Embedding-Silverlight-Videos-in-Community-Server.aspx

Creating a 'Path' Object in Silverlight

What is a ‘path’? A Xaml tag or object that defines a complex shape or polygon of some kind via a connected line which may make be an actual polygon and or consist of points, lines and arch’s. Everything from character to slices of a pie chart can be built using ‘paths’. Typically the ‘path’ is defined by its data property so typically a path is going to be something like this:

<Path Name=”MyPath” Stroke=”…” Fill=”…” Data=”…” …/>

At the very least, you may also use Canvas.Left and Canvas.Top or just place it in a canvas etc as well. A designer normally would be abstracted from actually building a path by hand but in cases such as building a pie chart one might want to write code to dynamically build slices of the pie chart programmatically and so therefore would want to know the syntax of the ‘data’ property on a path so they could compute it in their code.

How do I define a Path myself? To start with you must define a start point which is designated by ‘m’ (not case sensitive) and a point such as ‘M 10, 10’. You also need to define an end point which could be the same point so something like ‘L 10, 10’. So lets check out the types of things I can pass in.

If our start point is say ‘M 10, 10’ and we want to draw a horizontal line we can then do use the horizontal line command like this: ‘H x’ which might look like this then: ‘M 10, 10 H 150’. Next we can draw a line down using the vertical line command like this: ‘M 10, 10 H 150 V 150’ and if you use the L point from earlier we get a horizontal line and then a vertical line and a line from that point back to where we started which creates a triangle. (see the Path Sample Part 1).

So to get creative we can then use the Cubic Bezier Curve Command designated by ‘C’ so from the end point of our vertical line command we can then draw a Curve using 2 control points like this: ‘C 100, 100 200, 200 50, 50’. This shape would then give us this funky triangle shape with a weird ‘foot’ at the bottom.

We can also use the Quadratic Bezier Curve Command which would be ‘Q point1 end point’ where point 1 is our control point we could use the ‘Smooth Cubic Bezier Curve Command that is ‘S point1 end point where point1 is the control point for a regular curve or use ‘T’ to make the curve quadratic.

My favorite command is the Elliptical Arc Command which can be used to create a slice curve such as the curve of a pie slice. The syntax is ‘A size rotationAngle isLargeArcAngle sweepDirectionFlag endpoint’. These are the following:

· Size: this is the radius of the arch in pixels

· Rotation Angle: is the angle of rotation of the curve in degrees

· ‘Is Large Arc Angle’: is a flag that sets the render of the arch to be 180 degrees or greater if set to 1 where the default is 0

· ‘Sweep Direction Flag’: is a flag determining if the arc is to be drawn from a positive angle or not from the point if set to 1 but default is 0

· ‘End Point’ is just that the X,Y end point of our Arc

So if we use an arc definition like this: A 50, 50 200 1 0 100, 100 added to our sample (see Path Sample 3) we get a crazy but cool shape. That you really have to see to understand… note how the fill is applied effectively making 2 ‘shapes’. The entire definition would look like this:

<Path Name="PathElement" Data="M 10, 10 H 150 V 150

C 155,155 160,160 140,165

A 50, 50 200 1 0 100,100

L 10, 10"

Stroke="#3c5f0c" StrokeThickness="3"

Fill="#728f4a"

/>

Check out the SDK for more detailed on Path definition syntax or paths in general.

Silverlight 1.0, JSON and (gasp) PHP

So we are doing this really cool Silverlight app that I'll blog lots about when it goes live but one particular thing that is cool is our use of JSON. One one isues was that we are hosting this on a non microsoft approved web server... gasp (I know, those of you that know me will be in shock, but really when it comes to down to it I follow the money :) In any case so Mark writes this PHP service that takes some xml feed and transforms it to XAML but we also need some meta data so that when added to the application we can dynamically bind our silverlight 1.0 controls to the elements. Mark decided to try added a text area that would not be visible and put the JSON meta data there and poof, one little eval and we have our meta data and our transformed XAML... a little XSLT on the server in PHP and the source XML feed works way cooler then having todo in all clientside in silverlight...

JavaScript Class Structures

So 8 years ago or so I worked for this company and was hired to fix and admin tool they wrote in JavaScript... The system had 10's of thousands of lines and loaded as an HTA and looked and feeled like a win 32 app. This was cool but everything they used visual studio to debug everything feel to pieces. I spent a long time looking over the code and what bothered me was how they laid out classes. They would always declare a class (function) and then add functions to it effectively making them all global. It turns out when a move of a curlly braces so that it appeared more like a traditional class (minus the key word class) with the methods(functions) being nested in the class (top function). Like magic the application preformance went up and visual studio stopped blowing up on contact. It was really amazing. Since then I have been pretty sold on using a JavaScript class structure like this... Over the years my self rightousnous about JavaScript has grown to the point of having trouble getting in the door with my big head... What is the saying the bigger they are the harder they fall. Anyway in my self rightousness I over looked a little key word called 'prototype'. I don't know if it just wasn't around 10 years ago when I started JavaScript and came later or what but one day I wake up and there is class structure using prototypes that gives me heart burn as it keeps giving me flash backs to this one project. And alas I have learned something new. With all my winnying about properly structured javascript some one pointed out that oh look this key word makes all instances use the same copy... gasp choke [descriptive explative] what? So I ask to see the link and do a bit of research. and what do you know a better way of doing something.

So it turns out that if I declare my class with its properties and then declare using prototype my methods then all instances of the class use the same method. this is also how to extend core classes as well. (dah, as I have seen that before) So then the new rule is that proper javascript class declarations should look like this:

function myclass()

{

this.WhateverProperty = "";

}

myclass.prototype =

{

Method1: function( param1, param2 )

{

// some code

},

method2: function( param1, param2 )

{

//some more code

}

}

Yes I know my curly braces are matching and not the OLD school javascript standard but will all the other languages it just seems to be that JavaScript should follow suit, anyway this is how a javascript class should look like until I am proved otherwise... (hmm. setting my self up again). :)

Silverlight Host Loosing Mouse Capture...

So one issue we have had to deal with in Silverlight is loosing Mouse Capture. So inside the context of a silverlight application this isn't an issue. The problem is when we have a small embeded silverlight app, say a media player for instance that we want to be able to be dragged and resized dynamically accross the page over HTML content and back. We can build this application so it has a typical windows like drag corner that you can left down click on and then drag out to resize. In theory this works. The issue is if the mouse ever gets off of the silverlight app surface, which is very easy todo, Silverlight still thinks it has the mouse captured but events are no longer received and the on mouse up never gets fired. Further when you move back on to the Silverlight surface you still have managed to loose the mouse and code can get easily confused ie: say your using a flag to determine if the mouse is captured since silverlight currently doesn't have a 'isMouseCaptured' property etc.

So now we have framed the problem here is how we solved it. So even though the media player visually one size when we first catch the mouse down on the drag corner we actually change the size of the underlying aghost for silverlight to be an extra buffer of so many pixels. So now the aghost makes it much harder for the user to get the mouse off of the silverlight surface so we basically run around the screen and chase after the mouse. On drop then we resize the aghost to match the current drag corner position. On IE this works really well, on firefox it is more problematic but does work well if done correctly. On Safari on the Mac the drag works well but Safari is generally more touchy around the html dom.

Another point or rather surprise for me was making this same player work on Safari on the Mac... lets not get confused with Safari on windows which as of this post blows up on contact with silverlight. But anyway. on the Mac, Silverlight runs as smoothly as in IE especially with this particular mouse capture issue. Hmm... makes me wonder if it is just Firefox...

Path Performance Issues in Silverlight

So I was talking to Jared and Devin and the other designer/integrator types this morning and some one pointed out that when you create a Path that uses stretch and has a height and width Silverlight takes a huge preformance hit. Not sure why this is as it doen'st appear to be an issue in WPF that I know of but it seems to be a 'don't do that' in Silverlight...

Parsing XML in Silverlight 1.0 - Cross Browser

One problem we have seen and dealt with allot lately is parsing XML client side. My favorite solution I must admit is to just toss out XML and use JSON as it is so much more elegant. In the case of the ET Minisite we did as of late this turned out to solve a lot of our problems. But still what if I can't do JSON for whatever reason? if you only care about IE or even firefox that seems to be much less of a problem. But for a really cross browser experience I my solution is the XML document mini me. Granted this is a bit of hack (like much of JavaScript and Silverlight)... :) but it works well... IF your XML is pretty stable and IF there isn't to much XML weirdness like multipul nested levels and such but it works.

So the XML Mini me is a simple XML parseing engine written in Javascript. It only supports a limited subset of something like the real xml parser in .NET like XMLReader or even XMLDocument but it does so a few simple things including some simple xPath like behavior. I hestiate to say a subset of xpath as the mini me is so extremely limited. I also suspect that the silverlight team at some point will have a good XML parser built in to silverlight at some point but we will see. there is of course Silverlight 1.1 but if you can't do the .NET part it doesn't do much goo.

In Silverlight, you have the downloader object so its really reasonable get XML easily no matter what. So then using the XML mini me looks something like this:

var MyDom = new XMLDocument();
MyDom.LoadXML( SomeXML);

I tried to keep the syntax as famliar as possible. So now we have our XMLDOM called 'MyDom' and then to get data out we can do this:

var ArrayOfVAlues = MyDom.SelectNodes("//items");

In this case the mini me will return all the text values of all the items nodes in the dom in the form of an array. Underneath the covers the parser is just doing some 'string' manipulation but for small groups or data or simple RSS feeds or config files it seems to work well. large XML parseing would scary me preformance wise as would writing a more full featured parser that is entirely written in JavaScript.

Some things to note on the class is that it has an XML property like the XML parser we used to use in classic ASP but otherwise it only has two methods currently as those are the ones I need to get it working for my particular project. lets look at the XML it can deal with for starters, here is a sample:




http://www.hackingsilverlight.com


http://www.hackingsilverlight.com


http://www.hackingsilverlight.com


http://www.hackingsilverlight.com


http://www.hackingsilverlight.com




So in this sample using some simple xml our parse deals with it easily. In this case when we make a call to SelectNodes("//url") we will get an array of all the urls values with all the < ! [ CDATA stuff stripped off into an array. simple, easy and fast but easly breakable if you muck up the xml to much. So for the time being its a great stop gap and if JavaScript works then this works at it uses only intrinsic language features.

So the little XML mini me is great for simple stuff but when you really need to do real work with XML you really need a more robust solution that includes a real XML parser. Now that can prove problematic especially when it has to work in lots of browsers. To address this problem with my own work I wrote another class that wraps the cross browser functionality and wraps some key elements that I use. Typically I need things like all of properties of a given node in a list in the form of an array. Plus things like xPath and the like for Silverlight.

So the attached javascript class wraps the core functionality. It includes the HTTP request functionality and XML parsing with the other bits I 'might' need. Basically the class works like this:

var NewDOM = new XML();
NewDOM.Load("Sample.xml");

This code fires when the html page script code behind fires. When you call 'Load' and pass a url to an xml file it then depending on the browser it uses the appropriate HTTP request object to load the file and assign the onload event. On the XML files load the call back is called and the object does the appropriate processing. Once this does its thing we now can use it to parse our XML.

On the onload event for the page in my little test I make two calls to different methods. The same methods are supported on this class as the XML mini me but additional ones are included like 'SelectNodesAttributes'. Also I noticed in firefox by 'onload event gets called twice so I put a flag on it so it only fires once. So in this sample I call the two methods that return arrays but you can have direct access to the DOM and use xPath etc using NewDOM.XmlDocument.

Building a TextBox in Silverlight 1.0...

One of the problems I have seen a lot of is building full blown forms in Silverlight 1.0. For the most part, Silverlight apps have placed HTML over Silverlight. This certainly works, albeit not the ideal situation and Silverlight 1.1 promises to deliver us a real text box. However, in the mean time, I decided I needed a 'Silverlight 1.0' text box. So here is how I made one work.
In building a text block there are a number of key bits of functionality we need todo: making the control look like a text box, making the text box behave with focus like a text box (have a cursor) and getting key board events into the text box. If you can address these then things like wrap, overflow and size ratio's etc are pretty straight forward.

Actually making a control to look like a text box is not too hard. Basically we have a canvas with a nice boarder in XAML and you can make something that looks like a text box. In this case something like this:




Nice and simple. Now that it 'looks' like a text box we need to have a cursor when it gets focus... For the cursor you can do a number of other things but lets start with a little line rectangle. We set the size and starting position in our XAML and then make it invisable. In our code behind we wire up an event on the box so that on 'MouseLeftButtonDown' we get the event and set the 'textbox' into a focus state. Basically these means we set a flag, changed opacity and started an animation on the cursor to make it blink.

Now our text block looks like a text block when we click on it and the cursor shows up... Now we need to actually make it work. Todo this we can add a text block element and wire an additional event to the document object of the page to capture keyboard events. In our keyboard event handler we need to check the key codes against our look up table so we know what they mean and add the character to our text box. If we run our text block now we notice that this appears to work but the cursor doesn't move. So then we make our event handler move the cusor as well.

So in less then a few hundred lines of code we have a working text box. From here we now need to be able to deal with text overflow moving the cursor back and forth and sizes and ratios. When the control is wrapped nicely in a class and xaml file we can use it in our projects by just creating the class and passing in a destination or target and 'poof' instance text box. Almost like its built in.

Now to see if anyone is actually reading the blog... If any one is interested in the code let me know. :)

Ok Ok, so it seems some one actually does really read my blog. :) I feel much better so I'm going to post more on the text box.
Lets start by updating our xaml a bit.



now we have added the cursor and textblock we talked about earlier. In our code behind we have our event handler called:

TextBox_OnKeyPress and an initialization routine called InitTextBox. In the onload event we then call our iniatilizer and wire up the key press event handler. Now the trick here is that we are not wiring anything to 'silverlight' persay but in IE we wire it up to the document object like this:

function onload(sender, args)
{ InitTextBox(sender); document.onkeyup = TextBox_OnKeyPress; }

Ideally this all is wrapped in a consumable control which I'm will finish when I finish this cool char size algorythm so everything isn't hard coded but in the mean time this example uses a number of present values in the xaml and things like font size and base increment in the code. Also there is a GetWidth function with hard coded values that is used for moving the cursor on the text box surface.

So back to our function InitTextBox(sender). In the sample I did initially this function basically saves some references to different parts of the control such as the cursor and text box for manipulation and then it adds an event listener to the text box canvas. This function is around actually giving the control 'focus' effectiving. There are a few other things you might want todo that is not in the sample like code for getting the control out of focus etc. So our add event in the initializer looks like this:

TextBox.addEventListener("MouseLeftButtonDown",
function( sender, args )
{
IsTextBoxMouseCaptured = true;
TextBoxCursor.Opacity = "1";
CursorAnimation.begin();
} );

So when some one actually clicks on to the control we set our flocus flag to true and turn the cursor on by setting the opacity and turning on the blink animation.

Back to our key press event. This guy remember we wired up to the document object but we only want to get events when the control has focus. That means in the event handler we need to test for the flag and if true then we can do something. Here is a sample:

function TextBox_OnKeyPress()
{
if( IsTextBoxMouseCaptured )
{
var EventCode = Number(event.keyCode);
switch(EventCode)
{
case 48: SetCharacter( "0", ")", event.shiftKey );
break;
case 37:
TextBoxCursor["Canvas.Left"] = LastPosition();
break;
}

So in this case we see the flag test and then we grab our 'EventCode' from the keyboard and we use a case statement to determine what character this is and what todo. To make the example easier I removed all but two character examples. The first case we are dealing with the zero/close paren key. Note we call a function called SetCharacter and pass in three events. The SetCharacter function gets the current shown text, determines which charater we want based on shift condition adds the charater to the real text value we keep in a variable and then determines what text is to be shown places the text and calculates the cursor position based on another function called GetWidth which determines all the offsets from the base character size (this is the one that needs the cool algorythm so all the values are not hard coded...).

The last case is a move back button which calls the 'LastPosition' function and moves the cursor based on the character behind it. So that is basically all the key aspects of doing a text box in Silverlight 1.0.

}}

ASP.NET Server Controls in VS 2008 and .NET 3.5 and Sharepoint

Today is going to be a bit of a rant. Background on the issue is that in VS 2005 I have written server controls for ASP.NET and Web Parts for Share Point. Typically for building Share Point web parts I like to developement them as server controls to so I have this nice easy structure to work with until I have something that does basically what I want. The trick with a server control is basically basic C# stuff. First you make a class and inherit from your base control and then you overwrite a method and add some declaritive stuff and then you can use it on your page by using a register in the ASPX. Then you can use your tag to create an instance of your control. Also this can then be put into its own dll and added to VS's toolbar and you can pass the dll around to friends etc and everyone can have this cool dll. Now to turn the control into a web part basically you change the base class, add a few using statements and change the output method name, make sure its all in a dll and your good. So far so good right?
For a server control, the class basically looks like this:

[ToolboxData("<{0}:SomeName id=\"\" runat=\"server\" />")]
public class SomeName: System.Web.UI.WebControls.WebControl
{ protected override void Render(HtmlTextWriter writer)
{
writer.Write(PresentHTML()); // some method we make...
}
}


We also add a few bindable properties like id or width or title or something that might look like this:


private string _Id = string.Empty;


[Bindable(true), Category("Appearance"), DefaultValue("")]

public string id
{
get
{ return _Id;
}
set
{ _Id = value;
}
}


Again straight forward stuff. right? We also might add other functionality of course and we have it in a name space but this is the key bits above. Now to turn this into a 'WebPart' we make it look something like this:

[DefaultProperty("Text"),
ToolboxData("<{0}:MyWebPart runat=server>"), XmlRoot(Namespace = "MyWebPart")]
public class MyWebPart : WebPart
{
private string _Id = string.Empty;
[Bindable(true), Category("Appearance"), DefaultValue("")]

public string id
{
get
{ return _Id;
}
set
{ _Id = value;
}
}

protected override void RenderWebPart(HtmlTextWriter writer)
{
writer.Write(PresentHTML()); // our private method that does the real work...
}
}
not a big change and again pretty straight forward. I dont' show all the properties and methods like the one reference to 'PresentHTML' which is just a private method that returns a string. This is the basic stuff needed for sharepoint. The one other thing is to make sure you have the using statements that reference all our Sharepoint bits:


using Microsoft.SharePoint.Utilities;
using Microsoft.SharePoint.WebPartPages;
using Microsoft.SharePoint.WebControls;


and of course the sharepoint dll that your building to needs to be referenced. So to use the server control version you have to create a Register tag in your ASP.NET that looks like this:


<%@ Register TagPrefix="prefix" Namespace="ControlNameSpace" %>


then in the ASPX page we can add the tag for our control to test it without all the jumping around you need todo with Share Point. In this case it might look like this:



This is 'All Good' in VS 2005 but the other day (earlier this morning) I had to make it work in VS 2008 for embededing a webpart 'Silverlight' control into Sharepoint. So I got to the test page of the silverlight project and do basically the above and make a web part that writes out all my Silverlight stuff (actually it was Devin's Silverlight app). This way we care wire up bits that the web part needs to pass into the Silverlight class todo its thing for when it actually has to live in Sharepoint. I would have thought this easy enough...


So I add the class and set it up as a server control. I add the references, and the register for the tag prefix and namespace reference and then add a tag to the control that should create the silverlight app. I compile it and try to run it and it blows up entirely. After fighting with this for some time it turns out that you need to have an 'Assembly' reference in the register tag in VS 2008/.NET 3.5 for a server control to be able to run in ASP.NET 3.5. So then it looks something more like this:


<%@ Register TagPrefix="prefix" Namespace="ServiceNamespace" Assembly="SilverlightApp" %>


The part that bothered me is that if the class is in the same assembly as the rest of the site and we call out the name space and class specifically it should be able to find the default assembly since its run in that assembly... but alas I was wrong. Not that, that is a surprise but it always seems to surprise me when I am. :)

Silverlight 1.1 As A Sharepoint Web Part

Recently I did a project where I had to embed a Silverlight web part into sharepoint. You would think this is easy if you haven't done web parts before. At least thats what I thought. Granted I have done web parts but it always surprises how much jumping around I had todo. I found what worked best for me was to create the 1.1 project as a silverlight based server control in a web site that ran all the bits and then to install that in the same domain as the sharepoint server. At first I tried to make the web part duplicate what the server control did but for some reason Sharepoint would make it render is such a way that the silverlight ended up hidden... I tried a few things but decided to use an iframe. This way the web part only outputs a iframe pointed at the controls default page that loads the silverlight interface. Works like a charm too. :) That sounds good but the steps ended up being something like this:

Silverlight Site Configuration

1. Copy the Silverlight Website folder to Server Location.
2. Open IIS Manager (Start-> All Programs -> Administrative Tools -> Internet Information Services (IIS) Manager)
3. Open Server Node (local Computer)
4. Open ‘Web Sites’ node.
5. Open Default running web site node
6. Right Click web site node and select New -> Virtual Directory
7. When the Virtual Directory Creation Wizard comes up click next
8. Enter the correct Alias ‘[some name]’
9. Click ‘Next’
10. Click ‘Browse’ and find the physical location of the site directory by drilling down in the ‘Browse For Folder’ and then select ‘OK’
11. Click ‘Next’
12. Select ‘Run Scripts’ check box
13. Click ‘Next’
14. Click ‘Finish’

Web Part Configuration

1. Make sure the wep part project is compiled.
2. Copy the project to the Sharepoint server.
3. Copy the WebPart.dll to the bin directory under the wwwroot.
4. From the VS command prompt navigate to the bin directory under wwwroot.
5. gacutil the dll which should look something like this: gacutil –i WebPart.dll
6. from this same location in the VS command prompt use the command: sn –T WebPart.dll to find the strong name key. For example: 7dd6db7c5d0189b7
7. Find the Sharepoint Web.config by opening up the IIS Manager and selecting the core site and then right click on the web.config and file the file location.
8. Add a ‘safecontrol’ node to the safecontrols section like this:
Assembly="WebPart, Version=1.0.0.0, Culture=neutral,
PublicKeyToken=7dd6db7c2d0088b7"
Namespace="[some name space]"
TypeName="*"
Safe="True"
/>

9. Make sure the dwp file has a valid public token.
10. Go to the Sharepoint home page.
11. Click Site Actions and select ‘Show Page Editing Toolbar’
12. Click Page button in the toolbar.
13. Select ‘Add Web Parts’ -> Import
14. Click Browse and find the dwp file in the project.
15. Click ‘Upload’
16. Select ‘Add to: Top Zone’
17. Click ‘Import’
18. Close the import right hand bar
19. Select publish from the toolbar

So I'm not saying this is the right method or the best way todo it but it worked for me in my case... abit of a hack but well its Sharepoint :)

Wiring Silverlight Into the Browser History/Back Button

While watching a presentation Jason Cook was doing on flash he suggested some of the tricks used by other technologies could be used with Silverlight. The trick I was interested in was particularly being able to wire things into the browser history so that the back button of the browser does something other then go back to a different web page. This turned out the be a simple task. The way my sample works is that the html file (or .net page etc) that is running the silverlght application includes this Silverlight Paging class. At the end of the page is a block that initializes the class. On initialization it adds an iframe to the root pointing at one of two proxy files. The silverlight application then needs to add a proxy handler for setting application state based on any key it wants and each time application 'state' changes that you want to be a history 'point' you just call 'AddPage' with a key on the class. When some one then hits the back button the browser loads a different proxy with a different key stored as a query string value; which is then returned to the proxy handler or 'delegate' that sets application state. Slick as a whistle.

So lets look at that in more detail. Starting from the page that hosts our Silverlight application we can see that there is a script include. That script file includes our class and at the bottom of the page is our initialization code.



In the block of script at the bottom we have two lines of code. The first creates a global reference and instance of our class and the second line calls the Init method. If we go to our class source and go to the Init method and all it does is do a document.write and inserts an iframe that our class will use to create history paging entries.

In the paging prototype we also see two other methods. The method 'AddPage' loads page proxies into our iframe to create entries using our key value.

SilverlightPager.AddPage( "somevalue that indicates state");

in my sample project we just use an indexer in our Scene object on on mouse click on the button this happens:

// Put clicked logic here
this.indexer++;

SilverlightPager.AddPage(this.indexer);

Our next method is called 'OnReturnPage' which is actually called by our proxy pages. So in our Silverlight application we call 'AddPage' and pass in a key value each time we change state in and what that to be a history point. In our sliverlight load we also need to associate a delegate to the 'PagingDelegate' member of our class like this:

SilverlightPager.PagingDelegate = MyAppChangeStateHandler;

This will then be called each time our application calls 'AddPage' or clicks the browsers history button. In both cases the page proxies are going to call OnReturnPage and pass in our path which will have the key as a querystring value that we then strip off and pass into the PagingDelegate to change the application state. So then we get a little Flash Magic Mojo for our Silverlight app.

Popfly goes Beta

Yea, Popfly Beta has gone live and now is open for everyone. I'll have to go in and clean up some of the controls I did...

http://www.popfly.com

Silverlight - Associating Files in Visual Studio

So here is a Visual Studio trick I picked up from Josh in WPF land that applies to Silverlight. One issue we found in Silverlight was when we were building big Silverlight applications and custom user controls that the XAML and .js files were not associated to each other. But in Visual Studio if you know what todo its pretty straight forward. Then yoru 'XAML files can have JavaScript code files even if created seperating with different names.


Here is how you do it. When you silverlight solution and project is open in Visual Studio Right click on the project in the visual studio solution explorer. Click 'Unload Project'. If the solution is tied to Source control you will get a dialog 'Attempt to unload projects with shared checkouts' and you can select the option you want. So assuming you select 'continue' then the project is unloaded. Right click on the project and select Edit [project filename].csproj. You will see the project file open up in a raw xml edit mode. Fine the 'itemgroup' collection that has the file you want to make dependent on another file. Add a 'DependentUpon' node to the node that is your file and put the name of the file you want your file to be under. Save and close the project file. Then you right click the project and click 'reload' the project.
Its a cool trick and sure helped me clean up a few huge messy projects.

Silverlight, JSON and Automatic Design Asset Zip and index generation...

Lets say we have a huge silverlight application. And lets say that we have a lot of images, xaml and media that we use in our application. Silverlight does a great job of allowing us to use downloaders and catch events and deal with it but lets say we want to just do it once. Download everything in one file and then apply our assets. We also don't want all of the loose assets floating around our Silverlight apps directory structure...

From an architectural stand point this is a much cleaner method of keeping additional assets packaged especially when there is a lot of xaml and images etc and keep it as small as possible over the wire. Silverlight allows us to address all that by being able to download zip files. On the downside there is not dynamic way to know what is in the zip file and plus it is a pain to have to do it on your own. So this is how I addressed it.

First I built a windows application project in Visual Studio without any windows. I added directories with all my design assets and set them to be content and show up in the output directory. When you compile the project it builds out the executable and copies all the folders and assets added to the project to the output directory. From here Visual Studio starts the application. Although it doesn't have a UI persay it starts by looking for any zips that might be in the directory and deletes them.

Now the cool part happens... it looks at all the diretories and creates an index JSON file for each folder. It saves these all in the root of each directory and then proceeds to create zip files for each directory automatically. All I need todo is then have this projects zip files that are generated in the output folder be copied to my Silverlight project directory structure as a pre or post build event and I'm good. All these additional assets are kept nicely packaged and out of the main project. And I didn't have to mess with it on my own.

Also note that the attached project doesn't have the zip.exe that builds the zip via console commands passed to it. You can use the command line version of any thing like pkzip etc but you will have to edit the source of the main application to make it work. I have my own licensed copy of this command line tool that (pkzipc.exe) which is what the argument structure is designed for.