I Utterly Hate CSS Layout

4/29/2008 12:38:01 PM
I'm trying to revamp the look of my web site since it doesn't fit all that neatly into smaller resolutions. I'm working off a CSS layout that was given to me by the blog engine I am using. It sucks. Impossible to tell what is doing what to what. Of course, it partly do to my own poor understanding of CSS and also due to poor tooling support. VS 2008 has "better" CSS support but when you start mixing user controls, master pages, and more, it becomes unwieldy to say the least. Combine that with the piss-poor VS 2008 over FTP experience I get (long story on why I am doing that, but I clearly need to bring my code local and push versions to my web site).

Tags:

Rant

Cracking the Silverlight Streaming Direct Content Access Code

4/29/2008 12:09:00 AM

I'm working on my presentation for the Iowa Code Camp, and I once again bounced into something that has really frustrated me with Silverlight and Silverlight Streaming - getting access to SLS content directly, without having to go through one of the existing SLS options.  Basically, if I host mycoolvideo.wmv to SLS, I want to be able to get an URL to that media file and pass it to my Silverlight media element on my HTML page and have it play the video.

As it stands "out of the box", SLS provides four basic options for getting to your Silverlight application.  The first three assume you have loaded an actual Silverlight application (manifest, XAML, script, etc.) to SLS.  The first one, and the one I have used most often, is to place an iFrame in your web page.  Something along the lines of:

<iframe src="http://silverlight.services.live.com/invoke/29367/AlmostLive1/iframe.html" mce_src="http://silverlight.services.live.com/invoke/29367/AlmostLive1/iframe.html" scrolling="no" frameborder="0" style="width:500px; height:400px"></iframe>

Option 2 is using a Live Control.  I won't go over the exact steps here, but its a three step process that ends up putting a remotely hosted SLS player on your page.  The third option is to provide a download of  your application such as http://silverlight.services.live.com/invoke/29367/AlmostLive1/application.html.  This is really intended for a kind of "desktop install" sort of experience.

Of these three "application" options, iFrame is the easiest but it forces you to upload an entire Silverlight app for each video. The downside is that if you want to have a themed media player experience on your web site, you are at the mercy of the style the media player has in the uploaded application.  Sure, I could make sure I upload the same player that fits into my overall site design over and over again, but what happens if I want to change my design.  I would have to go back and update all of those applications in SLS.  A royal pain.

Recently, SLS added a fourth option.  This option allows you to upload only the media you want to host in SLS (currently limited to WMV only), and not an entire SLS application.  This, at first, sounded like the perfect solution until I realized that the only way to play that media was to use another iFrame solution, such as

<iframe src="http://silverlight.services.live.com/invoke/29367/DSMHHH/iframe.html" scrolling="no" frameborder="0" style="width:500px; height:375px"></iframe>

This iFrame will then play your video using a standard media player design as shown below:

slickthoughtproductions

Again, this is not what I want since I have no control over the style of the player.  What I really want, and based on some web searches it seems like quite a few others do as well, is a way to design my own Silverlight player, host that player directly into my web page, and then reference only media that is stored in the SLS cloud.  Essentially, I want to write:

mediaElement.Source = "streaming:/29367/DSMHHH/DSM-HHH.wmv

Now I can change the look and feel of my site without having to update SLS but I get all the other advantages of hosting my media in SLS. 

There is a partial solution to this problem already.  I will let you, dear reader, read all the gory details on your own.  Laurent Kempé has a very nice article on how to get this solution up and running and it actually served as the inspiration for the solution I have come up with.  The basic process is replacing the standard silverlight.js file that most Silverlight tools provide and use http://agappdom.net/h/silverlight.js.  This new script file provides a javascript function called createObjectEx that you use in place of the normal createObject when instantiating your Silverlight application on a given web page.  The big thing that createObjectEx provides is a way to pass in initialization parameters, most importantly one in the format of "streaming:/<acctid>/<appname>/<filename>".  This is resolved to a valid url (the actual media file url changes over time, preventing you from storing content urls and using them later) for your content and is then assigned your newly created Silverlight media element.  This works ok, but it's not as nice as being able to just ask SLS for a valid url and then assigning that url to your media element since it requires a new media element be created with each all to createObjectEx.

In what is one of the biggest oversights I can imagine, it seems that neither the Silverlight team or the SLS team thought anyone would want to be able to just get a streaming url for a piece of content directly.  The most obvious scenario would look something like 1) launch my Silverlight app, 2) query SLS for a list of applications and associated media files, 3) display that list to the user in my Silverlight control, 4) user picks an application, 5) ask SLS for a current http address for a given media file from that application, 6) assign that url to the Silverlight media player for playback.  Of course, even simpler would have been for the Silverlight media element to accept a Source property in the streaming:/<acctid>/<appname>/<filename> format and have it resolve a good url on its own.  Alas, neither option was provided.  Since SLS came out a bit after Silverlight 1.0 (IIRC), I can forgive the lack of support in the SL 1.0 media element.  I have no idea what the SLS guys were thinking.  Even more surprising, is that as of Silverlight 2 Beta 1, the media element has not been updated to support this scenario either.  Nor can I find any official statements saying it will be since folks have already started to repeat the same question but now with SL 2 as the player.

I've been thinking of and tinkering with various hacks around this problem for a while but none of them worked they way I wanted or provided the simplicity I wanted.  I had really assumed that Silverlight 2 Beta 1 would solve this problem, and that was my thinking when I submitted the session abstract for the Code Camp.  Once I sat down to start building my content, it was very disappointing to find that I was SOL as far as getting the desired functionality I was expecting from SL 2.  Needless to say, it was a) very disappointing, b) the risk you take by assuming a feature will be in a Beta, and c) meant I was probably going to have to finally settle on some nasty, clunky hack that would belittle me in the eyes of the Code Camp attendees.  Certainly not what would be expected of the world's only self-proclaimed .NET Sex Symbol!

I figured I would give the ol' Internet one more surf to see if there was anything new on the topic before I got my hack on.  That is when I stumbled on Laurent's article.  The big "AHA" moment came when Laurent talked about how the createObjectEx actually returns a piece of javascript under the covers.  The returned javascript looks like this:

SLStreaming._StartApp("bl2", null
, {}, []
, [http://msbluelight-0.agappdom.net/e1/d/4065/8.w/63325188000/0.UZcUXMfJgIK0I0HcP-SQGzhvvVE/livewriterdemo.wmv]);

Well, well, well, there is a current and valid URL to the media I so desperately crave right there!  That made the light bulb click on.  You never see that bit of code when you check out your browser's source since its all handled under the covers but the foundation was there to get at the url I wanted.  I started digging into the silverlight.js file and figured out how createObjectEx went about it's business. After that, it became pretty easy to figure out what needed to be done.

The heart of the solution starts with recognizing that createObjectEx submits the streaming :/ parameter to services hosted at http://silverlight.services.live.com/invoke.  The GET request that returns the piece of javascript looks like this:

http://silverlight.services.live.com/invoke/local/starth.js?id=bl2&u=1209235530389&p0=/29367/DSMHHH/DSM-HHH.wmv

Let's break this down real quick so we know what we are looking at:

  • id=bl2 - To be honest, I am not really sure what this is.  The initial value will always be bl2 and in the silveright.js implementation the only part of the id that may change is the integer - bl is a constant.  Leaving it as bl2 doesn't seem to break anything.
  • u=1209235530389  -  u is equal to the total number of millseconds since the Unix Epoch (Jan 1, 1970).  I assume this is a way to randomize the generated URL across various servers for load balancing and also to give some kind of lifetime to the request.  and it lets you use the term Unix Epoch with friends and family.
  • p0=/29367/DSMHHH/DSM-HHH.wmv - this is the path to the content I am looking for.  Basically, my account ID (29367), application name (DSMHHH), and the media file I am looking for (DSM-HHH.wmv)

So basically, all I had to do was construct an xmlHttpRequest (javascript) or a WebClient (.NET) and pass in the appropriate URL, take the snippet of javascript that is returned to me, and RegEx it looking for my content URL.

javascript C#
function GetMediaUrl(AcctID, AppName,FileName)
    {
        var baseAddress = "http://silverlight.services.live.com/invoke/local/";
        var url = baseAddress +
                  "starth.js?id=bl2" +
                  "&u=" + (new Date().valueOf()) +
                  "&p0=/" + AcctID + "/" + AppName + "/" + FileName;
       
        if (window.XMLHttpRequest)
        {
           var oReq = new XMLHttpRequest();
           oReq.open("GET", url,false);
           oReq.send();
        }

        var r, re;                    
        re = new RegExp("http:.+\.wmv","i"); 
        r = oReq.responseText.match(re);

}

WebClient client = new WebClient();

client.BaseAddress = "http://silverlight.services.live.com/invoke/local/";

TimeSpan t = (DateTime.UtcNow - new DateTime(1970, 1, 1));
double timestamp = t.TotalMilliseconds;
string milliseconds = timestamp.ToString().Split(new char[] { '.' })[0];
string myUri = string.Format("starth.js?id=bl2&u={0}&p0=/{1}/{2}/{3}", milliseconds, acctID, appID, mediaFile);
string response = client.DownloadString(myUri);

Match mediaMatch = Regex.Match(response, @"http:.+\.wmv");
string mediaUrl = mediaMatch.Value;

You could certainly add more error checking code, make the javascript async, and other improvements, but these examples get the point across.  Of course, neither of these examples will work for a hill of beans if you try and use them in your web page or Silverlight app!!!  Why?  Cross-site scripting limitations, my friends.  Tim Heuer posted about the fact the SLS does not have a cross domain policy file (that policy file would let the above code work like a champ) and wonders why anyone would want it?  Well, Tim (who's greatness and tech wizardary far surpasses my own), I want to get my media stream!!! ;-)  Without that SLS cross domain policy file, we are forced to take our solution to the server and essentially remote proxy calls from our client to the SLS service.  Not ideal and if you don't have the ability to run your own code on your host server then this solution won't work.  All the more reason to harp on the SLS folks to get a cross domain policy file in place!

So with that in mind, I will show you what I banged out (banged being the operative word) to be that remote server proxy.  Disclaimer:  This code is totally whipped out on the fly.  It absolutely is spaghetti code.  It's a way for me to show you how to get the job done.  You could (and probably should) come up with something cleaner, more intuitive, <pick your better approach description and insert here>.  Probably the first thing I would change would be to put the output into some kind of syndication format like RSS or ATOM.  You could then publish your "TV channel" and others could consume it and play it pretty easily.  The only thing I haven't figured out, and it could certainly be because I am not a RSS/ATOM guru, is how to account for that fact that one "item" (or in our case SLS application) can have more than one media file.  It is different from a podcast RSS feed where one item equals one enclosure equals one audio file.  I'll let some one else figure it out.

Below are the two functions that are the heart and soul of my solution. Note, you can get all of the code I used to build this sample here.

string ExecuteSLSRequest(string url, string acctID, string password)

    {
        if (acctID == null || password == null)
            throw new SecurityException("Missing AccountID and/or Password");

        HttpWebRequest httpRequest =
                (HttpWebRequest)HttpWebRequest.Create(SLSSecureRoot + acctID + "/" + url);
        byte[] userPass = Encoding.Default.GetBytes(acctID + ":" + password);
        string basic = "Basic " + Convert.ToBase64String(userPass);
        httpRequest.Headers["Authorization"] = basic;

        HttpWebResponse httpResponse = (HttpWebResponse)httpRequest.GetResponse();
        Stream httpStream = httpResponse.GetResponseStream();
        StreamReader streamReader = new StreamReader(httpStream);

        return streamReader.ReadToEnd();
    }

and

string GetMediaStream(string appname, string filename)

{
    TimeSpan t = (DateTime.UtcNow - new DateTime(1970, 1, 1));
    double timestamp = t.TotalMilliseconds;
    string milliseconds = timestamp.ToString().Split(new char[] { '.' })[0];

    string targetUri = string.Format("invoke/local/starth.js?id=bl2&u={0}&p0=/{1}/{2}/{3}", milliseconds, SilverlightStreaming.Account.AccountID, appname, filename);

    HttpWebRequest httpRequest =
            (HttpWebRequest)HttpWebRequest.Create(SLSMediaServiceRoot + targetUri);

    HttpWebResponse httpResponse = (HttpWebResponse)httpRequest.GetResponse();
    Stream responseStream = httpResponse.GetResponseStream();
    StreamReader streamReader = new StreamReader(responseStream);

    string scriptResponse = streamReader.ReadToEnd();

    Match mediaMatch = Regex.Match(scriptResponse, @"http:.+\.wmv");
    string mediaUrl = mediaMatch.Value;
    return mediaUrl;
}

ExcecuteSLSRequest is used to do secure communication with SLS.  This provides access to the application list and the file list per application.  It is driven by the url you pass in, of which you will only be passing in two - empty (to get a list of applications) or application name, which will get you a list of all files in the application.  There is entire SLS REST API for managing your application, but I don't care about that right now. I just exposed an Applications property off of my helper class to fetch all of the applications and their associated media files.  The property uses ExecuteSLSRequest to build a list of applications.  GetMediaStream takes an appname and a filename and talks to SLS to find a current, valid http address for the given media file.  Pretty easy and useful in it's own right. I'm already thinking about how you could use this to redirect clients to download content directly from SLS - podcasts for example.  Can you say free streaming AND free storage!!!  I think you can.

As a simple example of using my helper class, take a look at SLSApplications.ashx below:

public class SLSApplicationsHandler : IHttpHandler {
    const double expireTime = 1;  // expressed in hours
    public void ProcessRequest (HttpContext context) {
        XElement slsXml = null;
        if (context.Cache["sls"] == null)
        {  
            SilverlightStreaming.Account.AccountID = "<yourAccountID>";
            SilverlightStreaming.Account.Password = "<yourAccountKey";

            Dictionary<string, SLSApplication> apps = SilverlightStreaming.Applications;

            slsXml = new XElement("ContentList",
                    from a in apps.Values
                    select new XElement("Content",
                        new XAttribute("Name", a.Name),
                            from m in a.Media
                            select new XElement("File",
                                new XAttribute("Name", m.Name),
                                new XAttribute("Size", m.Size))));

            context.Cache.Add("sls",
                slsXml,
                null,
                DateTime.Now.AddHours(expireTime),
                System.Web.Caching.Cache.NoSlidingExpiration,
                System.Web.Caching.CacheItemPriority.Normal,
                null);

        }
        else
            slsXml = (XElement)context.Cache["sls"];

        context.Response.ContentType = "text/xml";
        context.Response.Write(slsXml.ToString());
    }
    public bool IsReusable {
        get {
            return false;
        }
    }
}

It uses my SilverlightStreaming helper class to get the apps and files as XML from SLS and then uses LINQ to shape that data into the format I want.  I use the ASP.NET cache to store the result since it is unlike to change all that often.  The results are returned as XML like this:

xml

I have another file, SLSMediaStream.ashx, that returns a valid http url when you pass in a query string containing the appname and media file you want to access - http://somehost.com/SLSMediaStream.ashx?appname=xyz&filename=abc.wmv. The result is returned as a simple string (not XML).  The code is shown below:

public class SLSMediaStream : IHttpHandler {


    public void ProcessRequest (HttpContext context) {


        string app = context.Request.QueryString["appname"];
        string file = context.Request.QueryString["filename"];


        string httpStream = SilverlightStreaming.GetMediaStream(app,file);
        context.Response.ContentType = "text/plain";
        context.Response.Write(httpStream);


    }


    public bool IsReusable {
        get {
            return false;
        }
    }
}

You can check out a live version of SLSApplicaitons.ashx here (returns all of my Silverlight apps and files) and a Silverlight 2 Beta 1 "video player" here (this one is super lame - working on a better one for SlickthoughtTV and DeveloperMinute.com.  You could also do it in Silverlight 1.0 but I like SL 2 much better <grin/>).  I'm not a javascript guy at all so I didn't put together a javascript web page to work with the "API" and since you need some kind of play back capability anyway, I didn't see the point. You can get the source here.

Hope you found it useful.

Tags:

Number Five is Alive! Well, Sort of...

4/28/2008 4:53:00 PM

clip_image001Yes, an old school movie reference for those of you old enough to remember that movie. No hints on the title - go figure it out for yourself if you don't already know. Let me just say, it was one of the last movies where Ally Sheedy was still "all that". What does that have to do with anything? Well, Microsoft has launched RoboChamps (www.robochamps.com), a simulated robotics league that is open to academics, hobbyists and developers from around the world.  From the official announcement...

RoboChamps is built on top of the Microsoft Robotics Developer Studio(MSRDS) 2008 CTP, and uses that product’s robust, physics enabled simulation environment to remove the barriers of entry that exist for many today. This simulated league provides individuals with immersive 3-d environments, simulated versions of robots, and compelling scenario-specific challenges where they can win real robots.  Environments range from a maze to the surface of the planet Mars to downtown driving to robot rescue to soccer.  The top four finalists will be flown to PDC, where the competition moves to the real world and participants apply their code to real robots.

It looks really cool and fun.  Even the web site is cool.  There are six different types of robot challenges you can choose from - navigate a maze, build a Mars Rover-style robot to explore alien worlds, drive through an urban setting, build a rescue bot, a bot that wrestles, or head-to-head tournament action.  Work a check out!

Tags:

Slick Thoughts

New Spaghetti Code Podcast Available - Jon Stonecash on ORM

4/28/2008 12:51:17 PM

In this edition of Spaghetti Code, I sit down with Jon Stonecash and talk about Object Relational Mapping.  We start off with an overview for those new to ORM, and then start to look at the various solutions, challenges, and ways to get started.  We also chat about Microsoft's forthcoming Entity Framework and get Jon's opinion on how that effort is looking so far and what still remains to be done.  All in all a very informative interview - thanks Jon!

Tags:

Headlines | SpaghettiCode

Video of HHH Launch

4/25/2008 5:46:07 PM
silhouette_1
Here is a little video montage of the Heroes Happen Here Launch Event in Des Moines this week.  I had taken a lot of video of the Omaha launch earlier in the week, but and ID10T error on my part ended up wiping out almost all of that video. Note to self, having one of those hard drive based video cameras might not be a bad idea.  Any way, both events were fantastic and it was great to get to see some folks that I haven't seen in quite a while.  I'm a video editing newbie so hopefully this looks ok.  If you know anyone that went to the launch, make sure to forward on a link so they can check it out. 

Is it just me or does the HHH silhouette look a lot like me, only skinnier?????  Hmmmm....  good thing I start my Body For Life routine again.  I may have a career in silhouette modeling.

Double-click for full screen

Tags:

Headlines

Iowa Code Camp - Just About a Week Away

4/24/2008 10:06:54 PM

Looking forward to the first ever Iowa Code Camp next weekend.  It's shaping up to be a great event with over 125 folks registered already.  I'll be presenting and the speaker list is also impressive.  I'll be toting my vid camera along and hopefully will not hose things up like I did in Omaha (grrrrrrrrrrr).  I'm also hoping to maybe get a podcast or two recorded with some of the big brains that will be doing seassions.

Tags:

Slick Thoughts

Two Great Pieces of News

4/22/2008 8:41:26 PM

Which one to talk about first?  Hmmmmm, I will go with the new baby on the block.

ILM steps up to the plate again by getting a Minneapolis Silverlight/WPF User Group started. From the announcement

This user group is dedicated to anyone who is interested in learning all about SilverLight, WPF, Expressions, and XAML. We intend to provide a healthy mix of deverloper and designer focused presentations and discussions, and will meet once every month. If you are interested in hearing about the upcoming events then you can join the group at http://www.ilmservice.com/silverlight/Membership.aspx

The other piece of great news is the Jason Bock has the date for the next Code Camp locked in! Code Camp 5 will be held on Oct. 11th, 2008 at the New Horizons.  Special thanks to New Horizons for letting the Code Campers use their facilities for this great event.  Make sure to register now!

Tags:

Headlines

To Twitter or Not To Twitter? That could be a Tweet

4/21/2008 11:12:45 PM

Ok, I've been following the Twitter "thing" for a while now and have been going back and forth on the value of the service as a professional.  On a personal level, I have about zero use for Twitter.  I am not interested in a lot of the noise that comes across Twitter.  My personal life has enough commitments, noise, and distractions in it already.  "Hey look - Bob is at Outback".  BFD - I have a kid's soccer match so I won't be zipping over there to join him, and frankly, I really don't care he is at the Outback, even if I did have time since he would have invited me to go along if he was interested in my company. Call me anti-social (I'm not), but I'm not a fan of the "pop in". An extreme example perhaps, but at the end of the day, I like my "not connected" time.  I'm a firm believer that "always connected all the time" is not a good thing no matter how cool it may seem at first.  Yes, I know I don't have Twitter in my face, but if you don't, what is the real value of it as compared to the myriad other forms of communication we already have.

From a professional perspective, I have been thinking about the value of Twitter to my job with Microsoft.  While I am not entirely convinced that there is a great deal of value, I stumbled across this blog post on the 17 Ways You Can Use Twitter- A Guide for Beginners, Marketers and Business Owners that has caused me to re-evaluate its value proposition.  For good, bad or indifferent, a large part of my current job is marketing.  While I consider myself a techie first and foremost, I find myself needing to think a lot about marketing.  That is not entirely a bad thing since it has caused me to stretch a bit and learn some new skills. When it comes to social networking (not thinking just about Twitter), there are a lot of different pivots, but the two that I am most interested in are how social networking aids or detracts from building your personal brand and standing in the community (and in my case, in particular, the developer community) and the value of social networking as an overall tool to EFFECTIVELY reach audiences with IMPACT.

Looking at the first issue, I can certainly see how Twitter can add to your ability to build brand - if used wisely.  The article I linked provides some great ways to go about doing that.  Not all of the 17 different ways of using Twitter apply to me, or at least, I don't want them to apply to me. ;-)  I view Twitter through the lens of being a communication medium for my role with Microsoft as opposed to being about me as an individual.  I envision using Twitter to send out notifications about important info, new podcasts being conducted or posted, when I am at a developer event, etc.  It will certainly not be about me going to O'Malley's or that I am in the bathroom (yes, I have seen a Twitter from someone saying they were in the can - sheesh!).  Doing those types of things allows my core market to be plugged in better and more "immediately" and thus have more of a connection.  I see value there.  So with that in mind, I set up a Twitter account with the not so imaginative name of MSFT_MSP.  I had thought about something a bit more catchy, but considering that someday someone else may be doing my job, I figured I would go with something the identified the role instead of the person. 

When it comes to reach, Twitter is as good a tool as any.  But from an IMPACT perspective, I think it is seriously challenged.  If someone only subscribes to a handful of Tweeters, then there is some impact.  But my second hand experience has been those that Twitter do so a lot and have a ton of stuff being dropped in their lap.  It's hard to stand out in that noise, much like it is hard to stand out in the blogosphere, but with Twitter I have to do it in only 140 characters! ;-)  Yes, those 140 characters can lead to something with more impact (is Twitter's biggest value that it makes tinyurl.com really useful again???), but again, I'm just one voice in a very crowded room.

Well, it's time to take the plunge.  I've got some recommendations on some good Twitter clients so I will have to check those out if I start following some Twitterers.  For now, you can follow me if you want! ;-)

Tags:

Slick Thoughts

Hitting the Road for Launch Events in Omaha and Des Moines

4/21/2008 1:16:02 AM

I will be heading down to Omaha tomorrow.  Monday will be flying and some customer meetings that afternoon and last minute launch prep that evening.  Tuesday is the Omaha launch at the Qwest Center (sold out) - hit me up if you are attending.  Wednesday will be customer calls during the day and then driving to Des Moines that evening.  I will be syncing up Javier Lozano (ASP.NET MVP)  for dinner and a podcast on Ruby, IronRuby, and more.  I'm really stoked about that interview.  Thursday is the Des Moines launch (still spaces available - again, hit me up if you are there) and then I will drive back to Omaha to catch my return flight Friday morning.

Tags:

Slick Thoughts

WPF and Data Visualization for Usability

4/16/2008 8:52:00 PM

I was at a customer meeting the other day, and we were going over WPF and what it meant for UI design and its value to traditional LOB types of applications.  We covered the usual glitz and glamour that makes WPF fun, but at the end of the day, not a lot of that matters to most LOB developers.  There are a lot of other "under the cover" reasons to use WPF (great databinding being just one example), but the conversation was predominately around the UI and the value of UI. 

wpfdatagraph Once you get past things like animations, styles, etc., the one concrete example that is often used to demonstrate the value of WPF is data visualization.  WPF certainly provide a great platform for data visualization.  When developers think of data visualization, they typically think of things like graphs, charts, and similar type of visual elements.  The picture at right is an example I took from one of the WPF demos I often show.  It graphs some financial data in a cool looking 3-D bar chart "thingy" and is a pretty good representation of what developers think about when they hear the words "data visualization".  For a lot of apps, that type of data visualization isn't needed so it has a "big whoop" factor when it comes to finding value in WPF.

wpfdatavisual This is not be surprising to some, but data visualization applies to a lot more than graphs and charts.  I've found that developers don't often think how visualization can be applied to "ordinary" UI design to provide a quantum leap in usability.  The picture at left shows a list box item from another demo I do.  Unlike the traditional item in a list box or drop down box that shows a simple piece of data (like a name), WPF allows us to template that item and visualize the underlying data in a much more informative and useful way.  In this example, we get not only the patient's name, but we also can see his age, medical conditions, and more (and no, I have no idea what all those little colored circles, squares and diamonds are).  From a usability perspective, the end user can now glean important "top line" data points about a given patient without having to actually click the item in order to display additional details in another window.  Another benefit is that this additional  information can help the user distinguish between multiple "John Smith" entries in a listbox because of the added detail.

Another benefit of this type of data visualization is that it frees up screen real estate that would have normally be used to display the detailed information on a given patient.  Granted, the new list box item template takes up more room than the traditional "line of text" items we are used to, but with WPF we can scale, shrink, or rotate those items in useful ways to maximize UI space.  Of course, we can always display some of those details in graphical ways that are easy to consume than traditional text boxes, grids, or what have you.  That is closer to the traditional notion of data visualization, but I do not necessarily mean charts and graphs.  Percentages displayed at color coded icons for quick analysis would be but one example.

So if you have dismissed WPF for you LOB app because you don't need "spinning buttons and bouncing balls", there is a lot more to WPF than just that. 

Tags:

Slick Thoughts

Powered by BlogEngine.NET 1.6.0.0
Theme by Mads Kristensen

About the author

Jeff Brand Jeff Brand

This is the personal web site of Jeff Brand, self-proclaimed .NET Sex Symbol and All-Around Good guy. Content from my presentations, blog, and links to other useful .NET information can all be found here.

E-mail me Send mail


Calendar

<<  September 2010  >>
MoTuWeThFrSaSu
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910

View posts in large calendar

My Twitter Updates

XBOX
Live

Recent comments

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2010

Sign in