Installing SQL 2005 on Vista
Easy way to redirect ASP.NET trace to Visual Studio Output Window
Goodies from Remix UK
VBScript: Microsoft File Transfer Manager
—————————
There was an error launching File Transfer Manager.
—————————
OK
—————————
Potential help with Silverlight Progressive Enhancement
Progressive Enhancement with Silverlight
Progressive Enhancement with Silverlight
I’ve been working with Yahoo’s YUI ajax libraries recently and I’ve been impressed (if frustrated) by their DataTable feature. What I especially liked about it was the idea to combine Progressive Enhancement (i.e. the ability to spruce up HTML by injecting more code and styles via javascript) with re-using the data inside the HTML table. Although I’m sure everyone wants to use nice REST/Web services to fetch their data there is still vast amounts of legacy code out there that is just pumping out HTML tables that have the potential for a good make-over. Now Ajax is fun and all, but for .NET developers Silverlight is the promised land since it uses almost exactly the same skill set. So my theory was, "why can’t I use Silverlight to enhance a HTML table and scrape the data from the HTML rather than a web service?". So that’s exactly what I did, please take look at the picture (I really should get a proper blog) to see what this all looks like.
The Start, boring HTML table
Here is a boring HTML table, no fancy bits, no resizing, no row selectors, no dragging, no cursor keyboard navigation, etc, etc.
<table>
<thead> <tr> <th>Surname <th>Forename <th class="bool">Available </th></tr>
<tbody> <tr> <td>Bassett <td>Berty <td> <tr> <td>Shore <td>Suzanne <td> <td> <input type="checkbox…
Fairly standard stuff, you should note that the table has an Id and the header for ‘available’ has the class ‘bool’, we’ll use those later. I put this Html into the SilverlightTest.aspx page you get when you create a new project.
How to pass arguments into Silverlight?
In order for Silverlight to work its magic over the Html table it first needs to know which table it should be working on, but how? Initially I decorated my classes with ScriptableMember and then registering the class with the browser using;
TableEnhancement tableEnhancement = new TableEnhancement();
HtmlPage.RegisterScriptableObject("SLTableEnhancement", tableEnhancement);
But it started to get muddy since I had to use clunky techniques in order to correctly discover which instance of the user control was running, etc. So I ended up simply passing the table’s id in Silverlights InitParameters (thanks to Mike Taulty for the hint);
<asp:Silverlight ID="Xaml1" runat="server" InitParameters="tableId=MyTable"…
Silverlight gathers that information in the Application, I chose to store it away in a public property;
private void Application_Startup(object sender, StartupEventArgs e)
{
string tableId = e.InitParams["tableId"];
this.TargetTableId = tableId;
this.RootVisual = new Page();
…
So now Silverlight knows the id of the element it should target.
How can Silverlight examine Html Elements?
This is quite easy too, Silverlight has access to the Dom;
HtmlDocument doc = HtmlPage.Document;
HtmlElement tableElement = doc.GetElementById(tableId);
…
Although this looks very easy the problem is that HtmlElement is as fine grain as it gets. So I’m grabbing a Html table which has lots of interesting properties and collections whereas HtmlElement boils down to GetProperty, GetAttribute and Children. Ok, so with a bit of to and fro-ing you can get the correct properties but I’d certainly like to see a few helper wrappers here.
How to create/configure the Silverlight DataGrid to represent the HTML table?
As with all grid technologies it’s really easy to get quite an advanced grid by simply binding to a source. But I wanted a little more control of the headers. So I set AutoGenerateColumns="False" and created the headers dynamically, be warned this is early prototype code so I’m making quite a few assumptions about the state of the HTML 😉
HtmlElement header = tableElement.GetProperty("tHead") as HtmlElement;
HtmlElementCollection headerRows = header.Children;
HtmlElementCollection headerCols = headerRows[0].Children;
HtmlElementCollection rows = tableElement.GetProperty("rows") as HtmlElementCollection;
Dictionary<int, DataGridColumn> columnHeader = new Dictionary<int, DataGridColumn>();
Dictionary<string, object> data = new Dictionary<string, object>();
HtmlElement trHeader = rows[0];
for (int i = 0; i < trHeader.Children.Count; i++)
{
HtmlElement td = trHeader.Children[i];
string headerText = ((string)td.GetProperty("innerText")).Trim();
string cssClass = td.GetAttribute("className");
if (cssClass != null && cssClass == "bool")
{
columnHeader.Add(i, new DataGridCheckBoxColumn
{
Header = headerText,
DisplayMemberBinding = new Binding(headerText)
});
}
else
{
columnHeader.Add(i, new DataGridTextColumn
{
Header = headerText,
DisplayMemberBinding = new Binding(headerText)
});
}
}
…
Ah, now you can see the role of the bool class, when a header is marked as bool I will create a checkbox column. You can probably guess that eventually I will pass that dictionary to the user control with the data grid so I’ll show that;
public override void CreateTable(Dictionary<int,DataGridColumn>headers, IEnumerable dataSource)
{
for(int i=0;i<headers.Count;i++)
{
DataGridColumn dataGridColumn = headers[i];
this.myDataGrid.Columns.Add(dataGridColumn
);
}
this.myDataGrid.ItemsSource = dataSource;
}
How to create a data source from the values in the HTML Table?
As you can see from the previous code snippet the data grid wants an IEnumerable data source. But my data is inside the rather nasty table hierarchy, so how do you create classes on the fly…well good old TypeBuilder that’s how. Now I must confess that I struck lucky here as while I was looking for exactly signature of a data source I happened across http://blog.bodurov.com/How-to-bind-Silverlight-DataGrid-from-IEnumerable-of-IDictionary. I used the sample there to create the classes on the fly, you have to watch that regEx – especially for spaces in your data. I also have to check the memory implications of on the fly creation cause I’ve been bitten by that before. But I’m pleased to say that it worked well.
How to replace the HTML table?
Standard DOM techniques work well for deleting the HTML table, a quick .Parent.RemoveChild worked fine. So everything worked? Well not quite. Silverlight takes a fraction of time to download after the document onload event fires. This means you can see the HTML table before it gets replaced. The simple answer to this is to style it hidden, if the Silverlight loads then it will be removed, if Silverlight doesn’t load then style it back. The problem was knowing if the user has Silverlight or not. The official line is to register the onPlugInError handler which fires when you don’t have Silverlight or just check to see of the Silverlight object is null. Indeed if you disable the Silverlight add-in in IE then it works fine. The problem is with other "unsupported" browsers, such as Opera, Chrome and Windows Safari. Although they don’t run Silverlight they do quite happily load the control. You can right-click and get all the properties of the Silverlight control…however although the light is on no-one is home. Nothing will run, no events will fire but the object is instantiated so the browser cheerfully reports nothing is wrong. It’s a real problem. Fortunately for my example I could simply show the element in the OnLoad and Silverlight will either run and delete it or not run and leave it there. I added a little timer to greatly reduce the opportunity of seeing the HTML version before the Silverlight kicks in;
<script type="text/javascript">
var timerId;
function showTable() {
clearTimeout(timerId);
var silverlightControl = document.getElementById("Xaml1");
// if the silverlight control hasn’t been loaded then…
if (silverlightControl == null) {
// show the original table
document.getElementById("MyTable").style.visibility = "visible";
// hide the download silverlight banner
document.getElementById("SLHost").style.display = "none";
return;
}
// just cause we’re here doesn’t mean Silverlight is active
// since other browsers still load the ActiveX face-plate
var tableElement = document.getElementById("MyTable");
if (tableElement != null) {
// I know the Silverligtht control deletes this element,
// so if it’s still here then show it, if I’m too quick for SL
// then it will still delete it any second now…
document.getElementById("MyTable").style.visibility = "visible";
}
}
function useSilverlight() {
// very quick timer to give everything a chance to settle down and
// process the message queue
timerId = setTimeout("showTable()", 5);
}
</script>
Silverlight performance difference between Mac & PC?
Remix UK replayed
Francis Bacon, data visualisations and the Turner Prize (?!)
One thing that struck me during the tour was how painters reaction to photography was similar to a number of recent presentations about data visualization. E.g. you can take a photo of someone but it doesn’t (normally) convey the inner person whereas a painter can show those inner attributes via their particular skill or style but in a way that is often quite foreign to our normal experiences. In a similar way many people are striving to show data in peculiar but compelling way. Oh well, not sure why I shared that but there you go 😉
Ah the Turner Prize. It’s all too easy to knock the artists that are nominated for the Turner Prize so it’s only fair that before making comment you visit it, so I thought. Hmm, I have to say that I didn’t see anything that was particularly challenging or innovative. That’s not to say it was, "all rubbish, a five year old could have done it" as I did like some individual items but prize winning? The bit I enjoyed the most was the comment wall at the end of the exhibition. Some were funny, some just venting their anger others asking for the prize themselves based upon the drawing on the comment card. I think the most telling comments were, ‘I’ll never get that back’ and a drawing of the recycling symbol with the word prize in it. Of course I can only hope to earn a tiny percentage of the money those artists will make, so who am I to throw stones? Good luck to them, I’d go for the work about zooming into pictures or the glass sculpture.
Silverlight User Group – Silverlight, XNA & Gaming
Completed event one frame after it is begun. So if you begin the
Storyboard again in the Completed event, you’ll have a timer that
executes once per frame’. Now it’s easy for me to say that without really knowing their game but there is a subtle difference between thinking that the storyboard will, "run as fast as possible" to ‘once per frame’. Richard also talked about Pete "slapping his wrists" for not using a time delta in the game loop (more on this in my aforementioned doc) but playing the game on my Mac it too suffers from the same problems I discovered. When you use a delta you effectively store up a number of moves. However, when you do suffer a "glitch" the effect (in this case) is that Minor Willy make sudden random "leaps" which means you end up crashing into the baddies. The game is almost unplayable for me 😦 Perhaps this is the curse of using Silverlight on a Mac??? Is was for a similar reason I removed the delta from Olop. Don’t get me wrong, I think the game is great, but I’d love to get to the bottom of the delta issue.
Overall I enjoyed the presentation and Pete’s enthusiasm for a area of computing that’s dear to me has certainly made me consider dusting off the game programming gloves and possibly even getting hold of XNA too.
Oh Pete (and other retro-gamers) the film you want to watch is King of Kong (a fistful of quarters)