March 2005 - Posts

Valentin Iliescu has updated his Avalon chess program...

The 3D and 2D versions have now been updated for the March 2005 CTP.
If you have the Avalon bits, grab the source here.
I'm an abysmal chess player myself, but this program leaves me gobsmacked: I have to admit I take childish delight in zooming in and out of the 3D board.

As a side note, given the complexity of the application that was one quick conversion.

Oh, and in other neat-Avalon-stuff-for-March-CTP news, Mobiform Software have updated the beta of their graphical designer for XAML, Aurora (actually they did this a while ago but it just now occurred to me to mention it...and I'm talking to myself again, aren't I?)

An on-screen reducing counter for web applications

Target platform: JavaScript + DHTML, with an ASP.NET custom server control for the fancy verson

There is a certain subset of online applications which require the user to have a limited amount of time to perform a certain action, after which some sort of “out of time” action is taken. A typical example would be a booking system for a limited resource such as concert tickets or seats on a plane, where it's desirable to reserve the desired quantity when the customer makes their selection, but it's also necessary to free up the resource as soon as possible if for some reason the customer abandons the transaction (which may not involve specific activity on the part of the customer: the customer may for instance have been struck by a meteorite while filling in the online forms). The code I'll describe here lets the user know how much time they have remaining.

Required functionality would typically include:

  • A constantly updated display of the time remaining (for my purposes, in minutes and seconds).
  • Persistence (or the appearance of persistence) of the counter over multiple pages.
  • Automatic redirection to a “time's up, nya nya nya nya nya” page if the countdown reaches zero.

Obviously, the request/response paradigm (God forgive me for using that word) of the web is not well suited to the “constantly updating” etc. part, so it's a fair bet that this will be a case for client script.
It happens that back when much of my web development work targeted the client rather than the server, I had a great fondness for creating semi-transparent pseudo-buttons with CSS and having them zip around the screen (because obviously there's a great need for that sort of thing). The mad DHTML animator's friend is a function that glories in the name of window.setTimeout.
This specifies a function to be called once a specified number of milliseconds have elapsed - it doesn't take much imagination to see that a constantly updating display can be achieved by having it call its own containing function. Best of all, it's cross-browser (at least for the modern browsers).
Sooooooo anyway, a function to count down from a given starting minutes/seconds value on-screen, updating the value of a “Countdown1”  could be as follows:

function decrementTimer(minutes, seconds)
{
  
var min = new
Number(minutes);
  
var sec = new
Number(seconds);
  
var
redirectPage = "timedout.html";
  
if
(min>-1)
   {
     
document.getElementById('CountDown1').innerHTML = (min>9?min.toString():'0'+min.toString()) + ':' + (sec>9?sec.toString():'0'+sec.toString());
     
if
(sec>0)
      {
         sec--;
      }
     
else
     
{
         min--;
         sec = 59;
      }
      window.setTimeout('decrementTimer(' + min + ',' + sec + ');',1000) ;
   }
   
else
   
{
      location.href=redirectPage;
   }
}

If you wanted to make that a reusable script-only solution it would be a good idea to make the span name a parameter as well, otherwise it's pretty workable as it is.
However, being an ASP.NET developer (among other things) I want a control that I can add to my toolbox, drop on to the page as necessary, set a few properties on, and preferably never worry about the fact that there is client script under the covers.
So here is our timer encapsulated in an ASP.NET custom control:

using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;
using System.Text;

namespace DalySoftware //Obligatory dorky namespace name
{
///
/// Reducing timer for web pages
///
   [DefaultProperty("RedirectPage"),ToolboxData("<{0}:CountDown runat=server>")]
   public class CountDown : System.Web.UI.WebControls.WebControl
   {
     
private TimeSpan timeSpan = new TimeSpan(0,30,00);
     
private string redirectPage = string.Empty;
     
[Bindable(
true),Category("Behavior"),Browsable(true),DefaultValue("")]
     
public string RedirectPage
     
{
         
get {return redirectPage;}
        
set {redirectPage = value;}
     
}
      
[Bindable(false),Category("Behavior"),Browsable(true)]
     
public TimeSpan TimeSpan
     
{
        
set {timeSpan = value;}
        
get {return timeSpan;}
     
}
     
protected override void OnPreRender(EventArgs e)
     
{
         
string script;
        
const string scriptKey = "CountDownScript";
        
const string startKey = "CountDownStartScript";
        
string startScript = string.Format(" decrementTimer({0},{1}); ",timeSpan.Minutes,timeSpan.Seconds);
        
StringBuilder builder =
new StringBuilder();
        
builder.Append(" function decrementTimer(minutes, seconds){");
        
builder.Append("var min = new Number(minutes);var sec = new Number(seconds);");
        
builder.AppendFormat("var redirectPage = \"{0}\";",redirectPage);
        
builder.Append("if(min>-1){");
        
builder.AppendFormat("document.getElementById('{0}').innerHTML = (min>9?min.toString():'0'+min.toString()) + ':' + (sec>9?sec.toString():'0'+sec.toString());if(sec>0){{sec--;}}else{{min--;sec = 59;}}",
this.ClientID);
        
builder.Append("window.setTimeout('decrementTimer(' + min + ',' + sec + ');',1000) ;");
        
builder.Append("}else{");
        
builder.Append("if(redirectPage!=\"\")location.href=redirectPage;}} ");
        
script = builder.ToString();
        
if(!Page.IsStartupScriptRegistered(startKey))
           
Page.RegisterStartupScript(startKey, startScript);
        
if(!Page.IsClientScriptBlockRegistered(scriptKey))
           
Page.RegisterClientScriptBlock(scriptKey,script);
        
base.OnPreRender (e);
     
}
  
}
}

In the real world I'd have some spaces between several of the line blocks, but transposing code from VS to the web is no fun and I'm tiring fast...
The JavaScript constructed by the StringBuilder in the OnPreRender event override is essentially the same we started with, except that the redirectPage is initialised by server-side code with the value of the RedirectPage property of the custom control, and the  in which the time remaining is displayed is identified by the custom control's ClientID property. 
In addition to RedirectPage, the other public property of the control is TimeSpan, which is a ,er, TimeSpan which we use to set the starting number of minutes and seconds from which to count down. Both RedirectPage and TimeSpan are exposed on the control's property grid.
Anyone who's still awake may recall that I mentioned persistence across pages as being a requirement: this is actually quite simple with ASP.NET. Assuming that there is a value stored somewhere that represents the time we started counting, all we have to do is initially add our time limit to this value to obtain a “time's up“ time, and whenever the page (or a new page featuring the counter) is to be displayed obtain the difference between that time and the current time (as a TimeSpan), using this to set our TimeSpan property.
And Bob's your uncle.
The resulting control is fully stylable. In its current form it does not implement INamingContainer, and if you place more than one on a form only the first will actually be displayed, but in view of the intended use I think that's acceptable.

March 2005 CTP progress

I just installed the February VS 2005 CTP and the March 2005 Avalon and Indigo CTP on the tablet I have from work (er, I mean the tablet the NZ taxpayers have...I am one after all). I haven't had the chance to try anything yet, but I have been able to confirm that I do have a working development environment.

Which is nice.

And now it's definitely time for bed. Happy Easter everybody.

March 2005 Avalon and Indigo CTP (updated with correction appended)

I downloaded the new bits (currently available for MSDN subscribers, shortly I hope for everybody else) the other day...now I'm eagerly awaiting Visual Studio 2005 Beta 2 (I think it will be simplest to install the latest goodies in my test environments all in one hit, and otherwise I'd be having to install the February CTP of the .NET Framework v2.0 anyway - I hope to God that this CTP actually does work with VS2005 Beta 2 when that comes out). I can't wait (well obviously I can, since I am, but you know what I mean) to get to grips with Indigo - I liked the PDC version, but it's been a long wait since then. I'm optimistic that it will not be deserving of my proposed slogan for WSE (”WSE - Because .ASMX Doesn't Make You Lose The Will To Live, So We  Had To Have Another Go”).
I just recently got seriously into Avalon for the first time since the PDC bits, so naturally it has now changed quite drastically, as promised. This is understandable however (and hey, it's not even beta software yet, so what could we expect?). In fact this could be viewed as a sign of progress: in 19 years of professional software development it's been my experience that once a significant amount of work has been done on a project it becomes all but impossible to add new or improved features without having a drastic impact on what's already been done (it's obvious that that isn't going to happen when you haven't done anything yet). So the high number of breaking changes highlights the fact that there's now actually quite a lot of Avalon to break.

I recommend the just released article Introducing the March 2005 CTP: What's New in "Avalon" as a starting place.
Hopefully most of the breaking changes will serve as enablers for new capabilities rather than simply being the result of lexical and syntactical hair-splitting, although I have to say that just from reading the examples in the SDK I have already learned to despise StaticResource: there is a certain verbosity in the new XAML syntax that is not altogether appealing.
System.Windows.Document appears to have been significantly gutted (there goes my XAML CV...hopefully I'll come up with a March 2005 version soon though, if only for the appearance of the thing) :I'm not sure whether the tags that were removed were deemed superfluous and/or replaced by features of other new or existing tags, so I'll be keen to learn what the story is there.
I'll miss loose XAML.
I was disappointed to see that media functionality is still absent: maybe they're waiting to get all the perf issues sorted out before including video and sound bits.
Oh, and why was ImageEffect removed and does the functionality it provided still exist? (judging by the blank spaces in the SDK docs I suspect this area is being rethought for some reason).
PS. I hope Valentin Iliescu releases an updated version of his 3D chess program at some point: that's a beautiful piece of software.

I should mention that there are many additions and enhancements in this release (which I won't comment on in depth until I've had a play), including a larger selection of standard UI elements (although still no TreeView unless I'm mistaken, which I could be)

So once again, with equal parts of hope and trepidation, we lurch into the future.

Update 22 March 2005 20:40

As several people have pointed out (most recently Chris Anderson - it's amazing how many people read this thing whenever I demonstrate conclusively that I don't know what I'm talking about :-) ), VS2005 Beta 2 will not be compatible with the March CTP, as I was hoping. I originally thought it might be on the basis of the the references to Beta 2 in the WinFX SDK docs, but they are as we all understand a work in progress so I shouldn't have read too much into that.
This creates something of a challenge when trying to make economical use of testing resources, but such is life. I've found C# Express to be an excellent tool for playing around with Avalon, so it's a bit annoying that there doesn't seem to be an .iso file available for the Feb. CTP in the MSDN subscriber library (there is for VS2005 Professional, but it's over 3G. Urk)...the alternative of downloading the setup file for the C# Express Feb. CTP and then going through the online setup process to drag down the rest is too crappy to be seriously contemplated.
So I think I'll bide my time and wait. For whatever. And so on.
In the meantime I think I'll do a little more Windows Mobile stuff, the Atom API is calling (admittedly I think it's saying “You can't park there, mate“, but never mind)...

New Pocket PC Blogging Software Release (Update with details)

On the weekend I finally got around to installing the 1.0 version of Community Server (it's surprising how smoothly that goes when you actually read the installation notes). I then added the MetaWeblog support (which in this version is an add-on, somewhat to my chagrin) and set to work testing The Application Once Called Pocket Blog Writer And Now For No Particular Reason Called Diarist.
my aspxconnection pages.-->

The ReadMe has been updated with relevant bits about the current Community Server release, so I strongly urge anyone who downloads the app to read it (the ReadMe file I mean).

And I'll just finish with a reminder that it also works with .Text, Blogger (although not as well as if it used Atom), BlogX, BlogSphere and dasBlog. So there you go.

I've done pretty much all I want to do with it for now (although I might get around to adding that Atom support one day): it's odd how much work I ended up putting into something that just resulted from mild frustration at not being able to blog from my Pocket PC while I was at Tech Ed in Auckland last year, so now it's time I got on with other things. While I'll be pursuing more Windows Mobile projects and making available online any that I think people might find useful, I'll also be blogging about a broader range of topics than I have for the past 6 months or so: There are for instance a couple of “How-To” pieces (one ASP.NET and one Avalon) that have been gestating for a while and should see the light of day soon.

My CV in XAML

...(or “My Résumé in XAML“ for those of the North American persuasion).

Recently in a fit of madness I agreed to give a presentation on Avalon to the local .NET users' group, and one of the things I demonstrated was my CV as a stand-alone XAML document.
This is now available here for anyone who's interested: unfortunately my hosting site doesn't serve XAML files directly so I had to zip it up, which means that those who've installed the November 2004 CTP for Avalon will miss out on the “Click here and see it hosted directly in IE” experience they'd otherwise be enjoying (enjoying is possibly putting it too strongly, it's only my CV for God's sake), nevertheless it is a real live XAML document you can download and have a look at in the comfort of your own home, place of work, or wireless-enabled coffee shop etc.
My objective was to demonstrate what you can get out of the box by enclosing some simple markup in <Document...></Document> tags.

And also of course it's my CV (only without all the sex and violence, naturally).

Thoughts on SQL Server Express

I have often criticised Microsoft for their tendency to play to the “Enterprise” and disregard the needs and interests of smaller organisations and developers (particularly in the mobile space, but that's not relevant to what I'm talking about here).

However, I think SQL Server 2005 Express (the February Community Tech Preview of which is now available here) is an example of them getting it exactly right: a free product built on the SQL Server 2005 engine, with many of its advanced features (XML support and including the much anticipated or dreaded CLR hosting), and with the MSDE workload governor replaced by simple (and quite generous) limits: 1 CPU, 1GB addressable RAM and 4GB database size. And decent administration tools as well.

It actually works out quite well: I would argue that the stated limitations leave ample room for the requirements of a small business or non-profit web site, while a business with enough throughput to exceed them would be able to afford a retail version of SQL Server 2005. I believe the combination of a SS2K5 Express (it seemed like an abbreviation when I started typing it) with ASP.NET 2.0 will contribute to the growth of packageable web solutions (hopefully including some produced by yours truly), and enable us to give the LAMP crowd more than a run for their money - but more importantly help to replace brochureware sites with truly dynamic web applications as databases become a more viable option for more people and organisations.

And that will be nice (especially the bit where people give me money for writing web apps).