Html 4.1 Makes CSS Names Case Sensitve

2009 October 27
by echostorm

We recently had to change a bunch of pages to make sure that IE and Firefox rendered them in standards mode to support some Ajax controls. It’s simple enough to add the doctype and an x-ua-compatible line for ie. What shocked me was when it broke our image buttons. They were linkbuttons with totally valid css behind them. The css validated from css 1 to 2.1 and I was baffled until I noticed the button was rendering correctly on one page where by rights it shouldn’t.

I fired up developer tools in ie8 and firebug and saw that on the bad pages the proper class wasn’t getting picked up by the buttons at all. WTF!?!

Then I saw it. The name of the class on the good page was case sensitive while all the others were capitalized. Could it be so simple? Yea, yeah it is.

tl;dr If you’re doing a page in HTML 4.1 standards, make sure you css classes observe case sensitivity.

Bing Maps Silverlight Control With Traffic Cams

2009 September 10
by echostorm

So there is a CTP of the Bing Maps Silverlight SDK out there and with the discontinuation of the asp.net version it looks like this is the direction that Redmond is moving.   I’ve been playing with the controls for a few weeks now and thought I’d do a little tutorial on a practical use.  One of the many awesome things about using Silverlight for this is that it don’t bog down with lots of pins / objects on the map and we don’t have to deal with a lot of the AJAX and postback issues we would doing the same thing in a traditional ASP.net app.

So despite the bad things that people in PA have to say about PennDot, they do have a ton of public traffic cams up on the major roads so an enterprising user can check conditions if they are going anywhere around the city.

In this app we’re going to generate a map and pins for each cam which will pop their image into a modal child window for the user to view and refresh the image every 5 seconds

1

2

That done, the first thing we need to do is add a ref to the map assembly.

3

You can do it like this.

4

Then in the xaml on the main page we need to add the reference thus:

5

We also add the object to the grid and give it a name.  If you run the app now you should get a normal map.  For this we’re going to need a Child Window to show the image in, so lets add one to the silverlight project.

6

7

Now that it’s added, lets go mess with the xaml a bit.

8

It has it pretty well setup for us to begin with but we want to bump up the size a bit to make the images more visible and add an Image object to the grid.  We don’t need to set its Grid.Row property explicitly since it’s the only one there and will fall into place on its own.  Give it a name and jump to the code view.

I’m giving you all the code at once so lets just step through and see whats going on here.  First we’re taking a string in the constructor which we’ll see come in handy later and throwing it into a class variable.  We’re also setting up a DispatcherTimer which is almost exactly like an old school timer.  We preload the image and start the timer ticking every 5 seconds and instruct the callback to reload the pic each time.

9

We can also see that loading the pic is super easy.  Its important however to make sure we’re not caching the image or it’ll never change.  In most cases this wouldn’t be an issue as Silverlight does this to save resources, in this case we need the opposite.

Now lets jump back to the main window.

10

I grabbed the data off the pennDot website and put it into a nice little xml file.   It looks like this:

11

With that added we need to start creating pins for the user to click to see the camera footage.

12

Now lets do this with LINQ to XML, we’ll need to import the assembly because it doesn’t preload with Silverlight.

13

That done we can write a little query to grab the data we need.

14

Now we’ve got an anon collection we can loop through and add our pins.  We’ll want to put them all into a new MapLayer to make it easy to clear them all later if we decide to give the user the option to remove the pins and it’ll simplify placement.

15

For this example I’m just making little green Ellipses for pins but you could do something nicer with ease.  You can see that the URL to the different images is predictable if we know the camera ID so we set that up and create an anon method that will run when the user clicks on an Ellipse.  The event will create an instance of our child window and point it at the camera URL the user just clicked on.  When the user is done it will release the mouse.

Now we add the ellipse to the new MapLayer we created and place it in the correct location.  The loop complete we add the new layer to the map.   One last change.  We’ll do the user a favor and center the map near our cameras and zoom it in so that they’re pretty well visible.

16

Now lets see how we did.

17

And the camera

18

You can check out a live version here

Images and Parameters Broken in CrystalReportViewer

2009 May 28
by echostorm

 

I hate Crystal Reports.  I was on the verge of a nervous breakdown today after launching a well tested app and finding my reportviewer with broken images or with a mysterious javascript error saying Object Expected.

CropperCapture[2]

The deal is that Crystal requires the aspnet_client folder that IIS creates in your Default Web Site and is accessable to all the virtual folders that live there.

However if you try to deploy your site to a new website on the server to use a different port or subdomain using host headers you won’t have access to the aspnet_client goodness and your reports will be borked.

 CropperCapture[1]

You can either copy the folder into your application folder or create a virtual folder that points to the aspnet_client folder in the Default site.

CropperCapture[4]

and you’re golden.

CropperCapture[3]

I owe a co-worker with a good memory for putting me on the right scent to figure this out.  Hope this helps someone avoid the anguish this caused me.

Save User Data In Silverlight

2009 May 20
by echostorm

So I’m writing a little time wasting game that step-father 2.0 came up with.  It’s a sort of sudokuesque columns blend.  Of course we want to have a way to keep track of your top ten scores for bragging rights. 

Anyway, in Silverlight you get, to start out, ten megs of isolated storage on each user’s drive to work with.  You can prompt them for more space if you like but for our purposes we’ve got plenty of room for a little text file to store the top ten scores.   private

void SaveScore() {

List<double> scores = new List<double>();

string rawScores = LoadData(“scores.dat”);

/* If there are scores, read them in */

if(rawScores.Length > 0) {

string[] splitScores = rawScores.Split(‘;’);

scores = splitScores.Select(a => double.Parse(a)).ToList();

}

scores.Add(score);

/* Get the scores in order highest to lowest */

scores.Sort((a,b) => b.CompareTo(a));

/* Take the new top ten and semicolon delimit them */

string newScores =

scores.Take(10).Aggregate(“”, (a,b) => (a + “;” + b)).TrimStart(‘;’);

SaveData(newScores, “scores.dat”);

}

And the supporting methods..

private

 

void SaveData(string data, string fileName) {

using (IsolatedStorageFile isf =

IsolatedStorageFile.GetUserStoreForApplication()) {

using (IsolatedStorageFileStream isfs =

new IsolatedStorageFileStream(fileName, FileMode.Create, isf)) {

using (StreamWriter sw = new StreamWriter(isfs)) {

sw.Write(data);

sw.Close();

}}}}

private

 

string LoadData(string fileName) {

string data = String.Empty;

using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication()) {

using (IsolatedStorageFileStream isfs =

new IsolatedStorageFileStream(fileName, FileMode.OpenOrCreate, isf)) {

using (StreamReader sr = new StreamReader(isfs)) {

string lineOfData = String.Empty;

while ((lineOfData = sr.ReadLine()) != null)

data += lineOfData;

}}}

return data;

}

Empty Option in DropDownList Bound to LinqDataSource

2009 April 2
by echostorm

This has been driving me a little crazy.  Sure if it was a completely code side binding I could insert the empty row into the datasource myself but I’m doing lots of work in ListViews of late so that option is totally out.  I ended up finding the answer on StackOverflow.

<asp:DropDownList ID="ddlEditEmployee" AppendDataBoundItems="true"

runat="server"

DataTextField="Value" DataValueField="ID"

SelectedValue='<%# Bind("EmployeeID") %>'

DataSourceID="LinqDataSource2">

<asp:ListItem Value="-1">

None

</asp:ListItem>

</asp:DropDownList>

The AppendDataBoundItems bit is important too otherwise sneaking that default on in there is for nothing. Enjoy.