Page view counter
So Much Is Happening The Silence Is Deafening!

June has been a madhouse month;  I’ve been working 80 hour weeks as has just about everyone who has anything to do with Silverlight, and yet there has been very little noise.  It is, as they say, the quiet before the storm.

iStock_dawnXSmall

As you know, we can’t yet talk about the biggest developments,  but I can say that many of us are working on making sure that when Silverlight 3 ships the site is ready with videos and related material that is completely up to date. That means of course that existing videos must be checked for breaking changes, and new videos must be created to highlight the exciting new features in Silverlight 3 that have not yet been announced.  We expect to have a great deal ready on the first day, and to keep it coming over the first weeks.

Much more about that as soon as the cone of silence is lifted.

New Silverlight – New Projects

To coincide with the release of Silverlight 3, I’m starting two new projects that I believe will greatly enhance my ability to meet the needs of a very broad range of developers. 

One of the concerns voiced in the past year, for example, was that the videos and tutorials were fine as far as they went, but each stood in splendid isolation, with little connection to the reality of creating software. 

Yet, we also know that one of the great benefits of the How Do I video series is that a developer can watch any without having to watch them all. 

I have found what I hope will be a terrific way to provide the best of both: the open and documented  development of projects complex enough to touch on  nearly every aspect of Silverlight, and to raise many deeply related issues such as

  • Two Tools: Visual Studio and Expression Blend
  • managing data
  • web services
  • design
  • dealing with changing specs
  • patterns
  • code management
  • designers, developers, dezelopers and more
  • emerging best practices
  • real-world tradeoffs when resources are constrained
  • and dozens of other issues.

I’ve named the overarching project AgOpenSource -- an on-going development project that will be completely tracked,documented and explored within a wiki-document housed inside my blog.

AgOpenSource

AgOpenSource will consist of creating applications from initial brainstorming , through design, development, testing, delivery and what we are calling recycling.   Now, not every application will be developed fully and not every application will be a candidate for the entire process, but if we do in fact build something that works and if it has value for our site, recycling indicates that we would then use that application as part of silverlight.net.

The documentation for AgOpenSource explains that it will start out as a “Glass House” project in which the information flow will be pretty much one way. I’ll continue to create videos, mini-tutorials and so forth and I’ll also be building all the bits and pieces myself.

It is my goal, and I expect to achieve it quite quickly, to move AgOpenSource to CodePlex and to make it an Open Source project, as described in the documentation.  I believe that will greatly enhance every aspect of AgOpenSource (hence the name) and I very much look forward to that transition.

VideoWiki Reborn

The first application that we’ll tackle within AgOpenSource is the VideoWiki project that was conceived back in April. This project was discussed in a number of posts, but nowhere do I see a full “vision statement” of what it is. Clearly there is much brainstorming and “sketching” to be done.

A VideoWiki is best understood as a HyperVideo with interchangeable links. Briefly, and you can find much more detail in the VideoWiki page of the AgOpenSource documentation, a HyperVideo has links associated with various times, scenes or  events in the video.  When you follow the link you may be taken to additional information or even to another video.

With a VideoWiki, the set of links and where they take you are uncoupled from the video, and you may choose from a variety of links for any given video.  For example, imagine that when you choose our video on creating Out Of Browser applications in Silverlight 3, you are offered to watch it in our VideoWiki player. If you agree to do so, you are then asked which links you’d like:

  • Links targeted at programmers new to Silverlight
  • Links targeted at experienced programmers
  • A link set created by <famous author>
  • A link set for those who like lots of extra information
  • A link set for those who like extremely technical commentary

Once you make your choice, you load your video and your link set, and as you watch, links slowly appear in a window next to the video. If you click on one, the video pauses, and a new video opens with additional information.

The Better Videos Project

Starting the week of July 20, the previously announced Better-Videos project will begin to ramp up.  The effect, I believe will be more effective videos produced more quickly, but this is an experiment in the truest sense; no one knows what the outcome will be.

Business success team

 

 

 

Because the internal day-to-day progress of this effort is not directly related to Silverlight programming,  I’ve sequestered the blog entries  about the Better-Video project in the Video Bloglet that you can access from the sidebar on any page

SideBarBetterVids

 

From Twitter to Tutorials

Neither of these projects will slow down the other avenues for information and interaction. In fact, I expect to add more. For now, here is what I see as the pyramid of information flow.

Short Bursts – Twitter

Mini-Articles & Flashes – Quick Bits

Substantive Articles – This Blog

Diary of the BetterVideo Project – Video Bloglet

The AgOpenSource Project – the AgOpenSource Wiki

Deep Dives Into Silverlight – Mini-Tutorials and Videos

Extended Analysis of Silverlight Programming – Full Tutorials

Social Networking? Facebook, LinkedIn, My Books & Photos

Timing

Timing is everything… and while we’ve not announced the release schedule for Silverlight 3, I can say that  I expect to be finished with my sequestered work before I come back from vacation (mid-July). At that point I will pour myself into AgOpenSource and my other projects, keeping ahead of the curve and responding to the three drastically different needs of our community:

  • Providing an On-Ramp for those who are new to Silverlight
  • Meeting the needs of Intermediate Silverlight Programmers
  • Providing raw meat for serious geeks ready to get off the carousel.
My single focus, however, remains the same: working Silverlight programmers. 

Right now, it is the silence before the storm, but by the end of July, the signal : noise ratio should approach 1.

Organizational Chaos Followup

About a month ago I wrote about getting organized.  Since it is Sunday and I’m saving my big announcement blog entry for tomorrow morning <smile>, I thought I’d take a moment for a not-so-quick follow up.   

Two Philosophies Lead To A Unified Approach

Some years back I found myself with the strong conviction that what worked (for me) was this: “Don’t organize on the way in, search on the way out.”

Every time I forget this premise, and fall back into the habit of creating dozens of small categories in which to stash things away, I end up with lots of mis-filed papers and socks all over the floor.

[By the way, I have no idea if that was an original insight, or one that I swiped from Ed Belove, probably when he described Lotus Agenda. (So many of the good ideas I’ve heard over the past couple decades were actually Ed’s.)

Since I last wrote, I discovered what is probably the only popular self-help book I fpimd worth the cover price (though I still think it could have been edited down to a white paper):  Getting Things Done by David Allen.  Of course I’m not the first to discover GTD (as it is known); the book is a massive best seller (which I admit is often a bad sign).

More related than might appear at first, the essential message of GTD , at least as filtered through my brain, is:  “The more you keep in your head the less you can think about what you need to do so get absolutely everything you have to do or remember out of your head. The only way you can do that is if you have a system you trust 100%.  You must trust that the system won’t lose anything, and you must trust that the information will be there (proactively in my case) when you need it.  That is to say, you have to trust that the information will be stored more reliably and retrieved more reliably in the system than it would be in your head.

This apparently is a hurdle for a lot of folks, but I have absolutely no problem believing that a well designed system, properly backed up can do that. I’m reasonably convinced that silicon is faster and more reliable than meat.

Once I dump all my tasks, trivia, notes, things to remember and things I have to do but not yet into a sufficiently reliable system, I’m freed up to do what meat does much better than silicon: set priorities and make judgments.

Assembling the Right System

The time for writing my own system has passed. There are enough pieces out there that it is just a question of finding them and plugging them together. That took a little doing (and this real intention of this note is to save you the work of recreating that experience!)

For a while,  every “solution” created more problems than it solved.  But with a bit of refinement and a willingness to spend more money on applets than one would think possible, I believe I have found solutions that meet the specifications: they allow me to keep virtually nothing in my head that isn’t relevant to something immediately actionable, yet with total confidence that what I need will be immediately retrievable when needed. Even better, the system will alert me when that time arrives, and since I’m notoriously unaware of time passing that is a very good thing indeed (I asked my wife if it was lunch time yet, at 11pm just last week). 

Stringent Requirements:

For me to turn over so much responsibility to any system, I must have an enormously high level of confidence, and thus the system must meet the following outrageous set of requirements.

Information: Be able to save any bit of information that I receive or stumble upon in email, on the web, in conversation, in IM, on the phone, while driving, in short: any where at any time,  and store it 100% reliably and be able to retrieve it no mater where I am, with at least 95% fidelity,  in less than 3 seconds.

Responsibilities: Capture every task
, personal and work, instantly and then let me forget them until it is possible to take an action, and then alert me immediately that an action is both possible and necessary.  Allow me to set priorities and to aggregate tasks into projects, and to add these tasks from anywhere at any time and to be alerted to and to retrieve them no matter where I am.

Email: Manage the 3,000 email messages I get every day so that I spend no more than 20-30 minutes a day reading my email,  but see everything important and never miss a critical email and so that I can retrieve any email I need within 3 seconds.

I could certainly have treated E-Mail as just more Information but it was much more efficient to treat it separately.

 

Information

I have to start by saying that I’ve built and bought at least a dozen systems that tried to meet the Information requirement. I believe it took the perfect storm of the Web, and massive advances in mobile phone technology to finally make this all work.  My solution here is centered around a single application: Evernote. The next image is Evernote running on Windows. I tend to throw just about every note into a single folder (cleverly named notes).  I make an exception for a few very obvious specialty notes such as business cards, passwords and my favorite: short term memory, the notebook in which I record my hotel room, where I left my car, etc.

EverNoteWindows

I can retrieve this information (or enter new notes) instantly on the Web,

EverNoteFireFox

or, even better, right on my phone:

ever

EverNote provides a clipping application that allows me to grab any highlighted text anywhere and just add it, or drag and drop into evernote, but my favorite feature is that I can take a picture and Evernote indexes the words in the picture, which I can then search for.  Hmmm…. I know we stopped at a good place to eat in Brewster on the cape; didn’t I take a shot of it for Yelp? Let me search…

brewster coffee

In less than a second it finds my picture and while the red arrow is mine the highlighting is provided by Evernote.  Very nice.

Spec:

image Be able to save any bit of information that I receive or stumble upon in email, on the web, in conversation, in IM, on the phone, while driving, in short: any where at any time,

image store it 100% reliably

image be able to retrieve it no mater where I am,  

image in less than 3 seconds.

[I’m going to table the issue of adding notes from the car for the moment, but see my discussion of Jott below)

Responsibilities

This is the hard one. I recently tweeted that working for Microsoft is like learning to juggle a dozen razor sharp plates a dozen razor sharp plates, while riding a unicycle on an escalator”

I’m told that many people feel that their memory leaks a bit, mine seems to leak a bit more than usual.

 

Young man kayaking down waterfall

Keeping track of my myriad projects, deadlines and responsibilities is critical to meeting the expectations of my bosses, peers, clients (that would be you) and myself. But I’m happy to say that David Allen says that trying is a losing strategy. Once again, the right answer is to turn it over to a system you trust. So I set off to find a 100% reliable system. 

I’ll spare you the details; the solution I found uses a back end web-based service with a phone-based front end, augmented by a call-in transcription service.

The backbone; the engine that makes it go and makes it available from everywhere at all times, is the unfortunately named Toodledo. The Toodledo interface is not simple, but it is powerful and it supports everything I need and then some. In fact, I switched from Remmeber the Milk (which I very much liked) to Toodledo because the latter was a much better fit with GTD and with the approach I as formulating.

 

Toodledo

Toodledo has three key features:

  1. It understands projects and sub-projects
  2. It works and plays well with the ToDo application that I use on my phone
  3. It is more than happy to sync with and to notify you of upcoming events by SMS, its own iPhone app, email, fireFox, twitter, Google, iCal, netVibes, pageFlakes, rss, jott, tSheets, outlook, VistaGadgets or Android. Pretty good

 

Toodledo is almost enough, but I need something much more immediate. To accomplish that, I added to vital pieces of software. First: ToDo:

ToDo

 

Appigo’s ToDo is a wonderful iPhone application for ToDo lists and project management, and is especially rewarding if you follow the GTD method as it understands projects, sub-projects, priorites, and most important Context (where you must be to act on a problem – no point seeing that you need to update the blog if you’re not near a computer.

I take it back, most important is that if you assign a due date and time ToDo will notify you. My one feature request would be to add a reminder date/time that is not the same as the Due date/time, but that is just a quibble.

 

The same set of tasks seen on the ToodleDo, looks like this on ToDo

 

 ToDo-Iphone

Almost There, but What About Ideas and Tasks that come to you on the highway?

The one missing piece in all of this is the requirement that I  be able to capture data and tasks any time, any where.  For a long time, it went like this: someone would ask me to do something (during a call) or I’d think of something important and then I’d face an interesting dilemma: which was the better choice:

  1. Wait until I could get off the highway to write it into my software by which time I was certain to have forgotten at least one important detail if not the entire reason I’d gotten off the highway in the first place

iStock_ Shrugging Man Medium

The second choice is to try to enter the information into my phone while driving 65 miles per hour among Massachusetts drivers

 

iStock_SadGirlverySmall

The answer is Jott. . Jott is a dictation service that lets you call in (or send a message from their phone app or their desktop app).They then transcribe your message and send it to whomever you like, including Evernote or Toodledo. Tweter, Outlook or any of your contacts.

 

jott

There are limitations to Jott’s voice recognition (see this article) but all in all it is just great. I can say “Jott ToDo” and add to my todo list while driving, such as “Jott Todo, pay speeding ticket”

GTD Bliss

Together, ToDo, Toodledo and Jott make a system that completely meets the GTD requirement: I can put every task, big or small, into the system with 100% assurance that I won’t lose it, miss it or have to think about it until it is time to think about it.

Spec:

image Capture every task, personal and work, instantly

image let me forget them until it is possible to take an action

image alert me immediately when  an action is both possible and necessary 

image Allow me to set priorities

image and to aggregate tasks into projects,

image and to add these tasks from anywhere at any time

image and to be alerted to and to retrieve them no matter where I am.

 

 

Email

I get about 3,000 emails a day and that is enough to treat Email separately.  Just a little analysis shows that my email breaks down (roughly) as follows:

  • About 2/3 comes from valuable lists but is not directed to me and is not immediately actionable
  • About 80% of what is left have me in the To or CC list but are not really to me specifically. I need to read them but most are FYI and while important to someone are not critical to me
  • We’re now down to 20% of 1/3 or a select 200 of the 3,000 daily messages. These 200 look important but only 1 in 10 really are. But those 20 message  must not be missed!
On any given day the proportions will change, unpredictably, but I strongly suspect that overall there is a normal distribution,  and further, what I’ve described is well within one standard deviation. What’s more, I’m wiling to bet, based solely on experience that this describes the contents of most corporate email inboxes.

 

The Best Laid Plans of Mice and Men

You may remember that my first approach was to have just 5 mailboxes:

  • Inbox
  • Act  (take action on this email)
  • Waiting  (pending someone else’s action)
  • Reference  (hold for future blos or videos)
  • Archive (can’t do anything with this now, hold on to it)

This lasted less than a fortnight. . There was just too much email to sustain it. 

I then created “rules” in Outlook to separate out the newsgroup emails and other chaff that I knew I could defer.  Worked fine until I found I had missed some pretty important emails. 

I’ll save you all the interim steps, and skip to the solution that is now working quite well.

Email Working…

Step 1, I created a small but vital second contacts list called VIP.  In it, I put the v-cards for anyone who I work for, work with or who is associated with a project I’m working on. Then I added anyone else whose mail I must not miss.  I will not be publishing this list :-)

Step 2: I created these mailboxes:

  • Inbox
  • VIP
  • VIP Urgent
  • Probably Not Urgent
  • Reference
  • Read
  • Discussions (under which are any number of mailboxes for each discussion area)

Every single message that arrives is copied to read and marked as read, and thus I can count on having a copy. 

Each of the following rules has an Except clause that reads: Except if my name is in the to or cc field or the sender is in the VIP list. 

There are then a series of rules, with that except clause that copies mail for discussions to the appropriate discussion and out of the inbox.

VIPRule

There is an additional rule that essentially says that if it is not for a discussion and doesn’t meet the exception criteria, put it in the “probably not urgent” folder.

Finally there are two vip rules, anything that is from someone on the VIP list that is marked urgent goes to the VIP urgent list and a template is used to send an SMS to my phone.  Anything that is from a VIP but is not urgent goes to the VIP folder. And then anything to me or cc to me but not vip stays in the inbox.

I can now read my messages in just the order I want, deleting as I go safe that a copy of everything is already in “Read”

1. ViP Urgent and VIP – never miss a message from a VIP again
2. Inbox  - read everything addressed to me
3. As time allows skim Probably not urgent and the discussions

Save anything I might want to come back to in reference and/or copy it to Evernote (discussed below) and/or make an entry in ToDo (discussed below).

All of this is supplemented by Copernic, an extraordinary search engine that is able to retrieve the messages I need in the specified amount of time, along with any matching files, contacts, images and so forth,

Copernic

Email: Manage the 3,000 email messages I get every day so that I spend no more than 20-30 minutes a day reading my email,  but see everything important and never miss a critical email and so that I can retrieve any email I need within 3 seconds

Spec:

image Manage the 3,000 email messages I get every day

image I spend no more than 20-30 minutes a day reading my email

image I see everything important

image I never miss a critical email 

image I can retrieve any email I need within 3 seconds,

 

An Evolving Story

I’m quite sure that this is not the final chapter, but there does come a point where organizing becomes a major distraction in and of itself, and as a friend once said, “How many frogs do you want to kiss to find an even-more-handsome prince?” 

I look forward to your comments and can only promise to be returning to matters of more immediate substance very soon.

Have I Missed The Bus?

About 5-10 times a week I get a letter that says something like this:

“Your book, Complete Idiots' Guide to a Career in Computer Programming  is wicked old. Do you still believe a programmer can be self-taught and is it possible for someone my age?”

Got one today and thought I’d answer here.

John,

The short answer is that the book is terribly out of date on its specifics (languages, technologies, etc.). There are a lot of new choices to make as to which technology to follow; I have completely hitched my wagon to Microsoft’s .NET since 1999, and as of 2007 I now work for Microsoft as “Silverlight Geek

With that information (and caveat) let me say unequivocally that the answer to both questions is yes, but it is far harder than most people expect, and the chart I often draw relates to how far people get in their first programming book. It looks like this:

Pctg of pages Read2

I totally made the numbers up, but based on talking with literally hundreds of readers and students. Folks start out with very strong intentions, but then the material gets difficult, their other job and family and real life intrudes and their resolution wavers.

So the first question is this: are you an autodidact? If not, save yourself a lot of grief, and start with a class, or better, a degree program at a good university.

That said, it certainly can be done; I did it (I had no choice, they kept kicking me out of school) and many of the best programmers I know did as well.  Of course, I started teaching myself when there was a lot less to learn.

And that is what I’d suggest you do; learn a lot less than there is to learn; narrow the field. Start by getting opinions from people who seem to love their jobs and who actually code for a living. Note that none of us will be right, but you may be able to eliminate some areas that are clearly wrong. Then pick a narrow field and learn that and nothing else for the first year.

Reasonable focus areas to consider:

  • Silverlight (Rich Internet)
  • WPF (desktop application)
  • ASP.NET / AJAX
  • Flash/ AIR (Rich Internet)
  • Java
  • Database
  • Open Source & Dynamic Languages
  • There are many others

I have had four career altering moments: 

  • Moving from general Unix programming to serious C coding on Unix
  • Switching to C++ / Windows
  • Switching to C# / .NET
  • Focusing on Silverlight

Warning: I now work for Microsoft as the “Silverlight Geek” and thus have a strong bias. But you know that.

A Crash Course

Let’s assume for the moment that you decide, correctly <smile> to learn .NET and focus on Silverlight and C#, learning the associated technologies along the way. Good choice.

iStock_MusicWireManMedium

Here is how I’d suggest you do it. Note that I’ll be recommending my books and others, but there are many alternatives. I’m also assuming money is not an object, but there are often free or nearly free alternatives.

  • Get a good development environment. A PC with at least 2, preferably 4 gig of RAM, a fast and big disk or two, and I strongly prefer two monitors, as big as you can afford.
  • Your development environment. Depending on your timing that will be Visual Studio 2008 or 2010.  Best is to buy the MSDN Subscription but they are expensive (ranging from $1K to 10K). You can of course just start with C# Express which is free.
  • Get a good introduction to the language and to .NET. I recommend Learning C# 3.0 (by me and Brian MacDonald).
  • Follow that with selected chapters from Programming .NET 3.5 by me and Alex Horovitz. (Just by the way, this is my most underappreciated books <smile>). For the first go ‘round, read chapters 1,2,8,10 and then save the book for later (you’ll be back)
  • OK, you’re ready for Silverlight. My guess is that by the time you’re ready we’ll have released Silverlight 3 and the new books on Silverlight 3 will be available as well.
  • I’d get at least two books on Silverlight (but I buy lots of books) and at least one on Expression Blend 3

Everything you need for Silverlight is at our web site. Start with my  Guide to Getting Started. (Note to self: update that page very soon!)

  • Go to our Forums often.
  • Sign up and read some of the better Silverlight blogs. You can find them by subscribing to Silverlight Cream.

Write Code, Publish Code

As soon as you feel you can write a Silverlight application that does something cool, make sure you put it where people will find it.  Then keep going. As soon as possible, get any work you can, paying or not. Contribute code to open source or anything else you can. Build confidence. Write articles on things you’ve just learned.

 

Best of luck!

 

jessesig

Where’s Jesse?

From now until sometime this summer, you may notice bursts of slow. Please mark this up to:

  • Summer vacation
  • Building embargoed videos so that we have lots of great stuff ready when Silverlight 3 is released
  • Updating older videos, tutorials, etc.,  so that they work great when Silverlight 3 is ready
  • Planning Silverlight 4 <smile>
  • Vacation (what??)
  • Cooking hard on the VideoWiki project’s new incarnation (more soon)

That said, MiniTutorials and Videos will still be a major effort, and will only ramp up even more once Silverlight 3 is live (which as you know is…. well, soon!)

But stay turned, what I lose in frequency I’ll make up for in incredibly astute and entertaining writing, breaking news, inside information, unauthorized leaks and internal gossip. Or not.

Meanwhile, I’ll be twittering and writing about my adventures and experiments in attempting to take Videos to the next level. Since it isn’t something everyone will be interested in, I’ll move it to a separate on-going story accessible as pages outside the main flow, from a link on the side bar, much like the Quick Bits.  The first entry is here.

Silverlight Validation in Detail

 

In a previous post I mentioned that Silverlight 3 has enhanced support for data entry validation. In this first of two mini-tutorials on the topic,  I will take you through the process of implementing validation in some detail.

DataValidation1

The key to understanding Silverlight validation is the division of logic from UI. In this case, the logic is delegated to the business object that the input control is bound to, and the UI is owned by the the input control (and the associated controls for displaying error conditions.) 

In the case shown above, the text box into which the user is invited to type an ISBN is the input control. Not shown is a business object (also, in these cases called a data object) that holds the rules about what makes for a valid ISBN.

UIAndLogicInValidation

On the left of this diagram is the UI. It is presented to the user as a text box, and implemented using Xaml. On the right is the business logic. A business object is created, in this case as a class in C# that represents, most often, an object in the user’s domain of concern – here a book.

The business object (the book) knows what a valid ISBN is, the UI does not.  The Business object determines if the value given to it by the UI is valid. If not, it throws an exception, specifying what is wrong. In this case, it might throw one of three exceptions:

  • "Must be exactly 10 integers long"
  • "Must be numbers or letter X"
  • "Checksum is invalid!"

 

The UI doesn’t know what the rules are, and the Business object doesn’t know how the UI will present the problem to the user (if at all!). And that is good.

Using Binding to Mediate the Validation of the UI By the Data Object

We are already asking the Binding Object to connect the User Control to the Business object, so it is the obvious choice to also pass along the value for validation and the objects response (if any).

Normally, when you bind a property to a TextBox you would provide the Mode and the Path, in this case, you add two more properties:

 

   1: Text="{Binding Mode=TwoWay, 
   2: NotifyOnValidationError=True,
   3: Path=ISBN10, 
   4: ValidatesOnExceptions=True}" 

The Business Object throws an exception if the data is not valid, and puts the reason in the Exception’s message. The Binding Object turns the exception into a message to the control, and sets the controls visual state from Valid to either InvalidUnfocused or InvalidFocused. What the control does when it changes visual state from Valid to one of the invalid states is entirely up to the designer of the control or whomever templates that control.

[We’ll look at templating error states in the second part of this mini-tutorial in a few weeks.]

For this to work, the control must bind using two way binding and it must support the new ValidationState group (you can see the validation states group very readily by beginning the templating process of any of the input controls that support validation out of the box as shown here:

ValidationStates2

 

As of this writing, the controls that will support validation out of the box at RTW are

  • TextBox
  • PasswordBox
  • CheckBox
  • RadioButton
  • ListBox
  • ComboBox

With the exception of PasswordBox, all of these already work in the Beta version.

Data Validation Step By Step

You now have all the pieces, let’s put them together step by step. 

The designer sets up a binding between an input control (text box) and a data object (the Book object) ensuring that

  • The binding is 2 way
  • The Control has Visual state to support Validation states
  • The BindingFramework knows to turn exceptions into validation state (flags)

The user is prompted to enter an ISBN into the text box. The value entered is not evaluated until one of two events; either the user leaves the text box (causing the text box to fire its TextChanged method, or the user clicks the handy Validate Now! button which invokes UpdateSource on the textBox’s TextProperty without having to actually leave the textBox.

In either case,  the data is given to the Binding Framework which passes it to the Data Object for validation,

ValidationStage1

If the data is not valid, the DataObject throws an exception to the BindingFramework. The Framework turns the exception into an instruction to the input control to set its validation state to Invalid. This will kick off a storyboard, in our case turning the border red, and when the user clicks in the control bringing up the error message from the exception which is passed to the control in its error message.

Datavalidation2

[This drawing based on an original image by Karen Corby]

Steps To Creating Data Validation

There are times when I find that I follow every word of a presentation but I still have no idea how to actually do it.  So here’s how.

1. Create a  new project

2. Createi a business object that is going to own data validation

3. Create two way data binding between one or more input controls from the supported list above to one or more properties on your data object

4. For each control you want to validate, create a setter on the bound property that tests for the conditions you want to validate, and throws an exception if the data is not valid. In the control, be sure to set the two flags (NotifyOnValidationError=True, ValidatesOnExceptions=True).

That’s it!  Honest.

Here is the complete MinPage.xaml for this example followed by the complete code behind…

   1: <UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   2:              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   3:              xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
   4:              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
   5:              x:Class="Validation_OutOfBox.MainPage"
   6:              Width="600"
   7:              Height="250"
   8:              mc:Ignorable="d">
   9:     <Grid x:Name="LayoutRoot"
  10:           Background="White">
  11:         <Grid.RowDefinitions>
  12:             <RowDefinition Height="1*" />
  13:             <RowDefinition Height="1*" />
  14:             <RowDefinition Height="1*" />
  15:             <RowDefinition Height="1*" />
  16:         </Grid.RowDefinitions>
  17:         <Grid.ColumnDefinitions>
  18:             <ColumnDefinition Width="1*" />
  19:             <ColumnDefinition Width="1*" />
  20:         </Grid.ColumnDefinitions>
  21:         <TextBlock Text="{Binding Path=Title}"
  22:                    HorizontalAlignment="Center"
  23:                    VerticalAlignment="Bottom"
  24:                    Grid.Row="0"
  25:                    Grid.Column="0"
  26:                    Grid.ColumnSpan="2"
  27:                    FontFamily="Georgia"
  28:                    FontSize="24" />
  29:         <TextBlock x:Name="Prompt10"
  30:                    Text="Please enter the 10 digit ISBN"
  31:                    TextWrapping="Wrap"
  32:                    HorizontalAlignment="Right"
  33:                    VerticalAlignment="Bottom"
  34:                    FontFamily="Georgia"
  35:                    FontSize="18"
  36:                    Grid.Column="0"
  37:                    Grid.Row="1"
  38:                    Margin="5" />
  39:         <TextBox x:Name="TenDigits"
  40:                  FontFamily="Georgia"
  41:                  FontSize="18"
  42:                  HorizontalAlignment="Left"
  43:                  VerticalAlignment="Bottom"
  44:                  Margin="5"
  45:                  Width="150"
  46:                  Height="40"
  47:                  Grid.Column="1"
  48:                  Grid.Row="1"
  49:                  TextWrapping="Wrap"
  50:                  Text="{Binding Mode=TwoWay, 
  51:                  NotifyOnValidationError=True, 
  52:                  Path=ISBN10, 
  53:                  ValidatesOnExceptions=True}"   />
  54:         
  55:         <Button x:Name="FillIt"
  56:                 Content="Fill With valid ISBN 10"
  57:                 Width="120"
  58:                 Height="25"
  59:                 Grid.Column="1"
  60:                 Grid.Row="2"
  61:                 FontSize="12"
  62:                 HorizontalAlignment="Left"
  63:                 VerticalAlignment="Bottom"
  64:                 Margin="5"
  65:                 Background="#FF06F616" />
  66:         <Button x:Name="ValidateIt"
  67:                 Content="Validate Now!"
  68:                 Background="#FFFFFF00"
  69:                 Width="120"
  70:                 Height="25"
  71:                 Grid.Column="0"
  72:                 Grid.Row="2"
  73:                 FontSize="12"
  74:                 Margin="5"
  75:                 VerticalAlignment="Bottom"
  76:                 HorizontalAlignment="Right" />
  77:      </Grid>
  78: </UserControl>

Here’s the complete code behind,

   1: using System.Windows;
   2: using System.Windows.Controls;
   3: using System.Windows.Data;
   4:  
   5: namespace Validation_OutOfBox
   6: {
   7:   public partial class MainPage : UserControl
   8:   {
   9:     public MainPage()
  10:     {
  11:       InitializeComponent();
  12:       Book b = new Book();
  13:       b.Title = "Data Validation for Fun and Prophet";
  14:       LayoutRoot.DataContext = b;
  15:       FillIt.Click += new RoutedEventHandler( FillIt_Click );
  16:       ValidateIt.Click += new RoutedEventHandler( ValidateIt_Click );
  17:     }
  18:  
  19:     void ValidateIt_Click( object sender, RoutedEventArgs e )
  20:     {
  21:       BindingExpression bindingExpression = TenDigits.GetBindingExpression( TextBox.TextProperty );
  22:       bindingExpression.UpdateSource();
  23:     }
  24:  
  25:     void FillIt_Click( object sender, RoutedEventArgs e )
  26:     {
  27:       TenDigits.Text = "059652756X"; 
  28:     }
  29:   }
  30: }

 

Finally, here is the business class/ data object

 

   1: using System;
   2: using System.ComponentModel;
   3:  
   4: namespace Validation_OutOfBox
   5: {
   6:   public class Book : INotifyPropertyChanged
   7:   {
   8:     public event PropertyChangedEventHandler PropertyChanged;
   9:  
  10:     private string title;
  11:     public string Title
  12:     {
  13:       get
  14:       {
  15:         return title;
  16:       }
  17:       set
  18:       {
  19:         title = value;
  20:         NotifyPropertyChanged( "Title" );
  21:       }
  22:     }
  23:  
  24:     private string isbn10;
  25:     public string ISBN10
  26:     {
  27:       get
  28:       {
  29:         return isbn10;
  30:       }
  31:       set
  32:       {
  33:          
  34:         if ( value.Length != 10 )
  35:         {
  36:           throw new ArgumentException( "Must be exactly 10 integers long" );
  37:         }
  38:  
  39:         char[] isbnAsArray = value.ToCharArray();
  40:  
  41:         foreach ( char c in isbnAsArray )
  42:         {
  43:           if ( ( !Char.IsNumber( c ) ) && c.ToString().ToUpper() != "X" )
  44:           {
  45:             throw new ArgumentException( "Must be numbers or letter X" );
  46:           }
  47:         }
  48:  
  49:         int runningTotal = 0;
  50:         for ( int i = 0; i < 9; i++ )
  51:         {
  52:           int val =  ( Convert.ToInt32(isbnAsArrayIdea.ToString()) 
  53:                  * ( 10 - i ) );
  54:           runningTotal += val;
  55:         }
  56:         int mod = runningTotal % 11;
  57:         int checkSum = 11 - mod;
  58:         
  59:         int isbnCheckSum = -1;
  60:         if ( isbnAsArray[9].ToString().ToUpper() == "X" )
  61:           isbnCheckSum = 10;
  62:         else
  63:           isbnCheckSum = Convert.ToInt32(isbnAsArray[9].ToString());
  64:  
  65:         if ( isbnCheckSum != checkSum )
  66:         {
  67:           throw new ArgumentException( "Checksum is invalid!" );
  68:         }
  69:  
  70:         isbn10 = value;
  71:         NotifyPropertyChanged( "ISBN10" );
  72:       }
  73:     }
  74:  
  75:     private void NotifyPropertyChanged( String propertyName )
  76:     {
  77:       if ( PropertyChanged != null )
  78:       {
  79:         PropertyChanged( this, new PropertyChangedEventArgs( propertyName ) );
  80:       }
  81:     }
  82:   }
  83: }

 

That’s it!

 

ecq100Example-Code Quality, GuaranteedThis code was compiled with Silverlight 3 (Beta) using Visual Studio 8 SP1 on Windows 7 (RC) and also on Silverlight 3 (Beta) using Visual Studio 10 (Beta) on Windows 7 (RC).   For more on this guarantee, please see this page.

And to think that I found it on Bing

Ever since I started writing books I check Google (and for the past number of years it has been Google) for my name every now and then; both for the ego gratification and to see if there is misinformation or unhappy readers or other stories I should respond to.

Bing

Not that long ago, like a good corporate boy I would Live Search (boy that was hard to make into a verb) for my name. Eh.

Today I tried Bing.  In the first page of searching images, I found an interview I gave last year at TechEd Barcelona, but was never able to track down.

TechEdBarcelona

Wow am I glad I’ve shaved off the dopey facial hair.

I was pretty impressed when I clicked on Biography. Somehow Bing culled through my 3MM entries and found 5,100 that were specifically biographical. Cool.  Here’s the first line of 6 of the first 10 articles found,

Bio
The other 4 had to do with me but were not really bios. Still, not bad.

I’ll be keeping an eye on Bing. Meanwhile, get ready to Bing yourself, don't be shy.

You can find out more on Bing.com

(Yes, this sounded a lot like hype, but I really liked it. And it is nice to see something new in searching)

What’s New In Silverlight 3

I had the pleasure of presenting What’s New In Silverlight 3 both at TechEd this year and then again to the Redmond .NET Developer’s Association,

Redmond

I think the best way to make this material available is to post my slides here along with the source code, and then to point to videos and blog entries that cover this material (either existing or as I create it in coming weeks).

Please note that this presentation was given using Silverlight 3 Beta.

  • If you are reading this and we are still in Beta, then you can get what you need by clicking on the image below, but please read the caveats carefully about using the Beta version.

GetStartedSL3

  • If you are reading this after we’ve released the RTW version of Silverlight, be sure either to obtain the updated version of the code or to proceed with caution as there may be small differences from the beta.

The slides are here as a zip file.

The Demos and Supporting Videos

3dFlip

For the first demo, 3d flip,  I recommend reviewing Using 3d Transforms Part 1 and Part 2.

For the second demo “The Slider and the TextBlock” you’ll want to look at the video Element to Element Binding.

The third demo is on Easing, and we have a good video on that here, as well as a mini-tutorial here 

Demos #4 and #5 are on Pixel Shading and bitmaps. Best we can do for you for now is this excellent video on Pixel effects.

The Bounce demo shows how messaging works and is so much fun you won’t need much to go with it.  After that you come to the demo for “based-on” styles.

Based-On Styles

I don’t have an entry for that for you yet, but one is coming very soon. For now, take a look at the following Xaml which is the heart of the demo:

   1: <Style x:Key="StandardButton"
   2:        TargetType="Button">
   3:   <Setter Property="Width"
   4:           Value="100" />
   5:   <Setter Property="Height"
   6:           Value="35" />
   7:   <Setter Property="HorizontalAlignment"
   8:           Value="Left" />
   9:   <Setter Property="VerticalAlignment"
  10:           Value="Bottom" />
  11: </Style>

We start by defining the style for a standard button, setting a width, height and alignments.  This style can be assigned within the Xaml to any button as follows:

   1: <Button x:Name="Button1"
   2:         Content="I am a standard button"
   3:         Style="{StaticResource StandardButton}" />

Now we want to create a Big button. A big button style is just like a standard button, except that it is taller and wider. Its alignment is the same.

   1: <Style x:Key="BigButton"
   2:       BasedOn="{StaticResource StandardButton}"
   3:       TargetType="Button">
   4:    <Setter Property="Width"
   5:          Value="250" />
   6:    <Setter Property="Height"
   7:          Value="50" />
   8: </Style>

You can see that what is key in this definition is the new BasedOn property.  You assign this new style exactly as you would any other style…

   1: <Button x:Name="Button2"
   2:         Content="I'm a big button"
   3:         Style="{StaticResource BigButton}" />

You can base a style on a style that is based on another style. In our final example, we’ll create a BigFont button that builds on the BigButton but sets a larger font.

   1: <Style x:Key="BigFontButton"
   2:     TargetType="Button"
   3:     BasedOn="{StaticResource BigButton}">
   4:    <Setter Property="FontSize"
   5:        Value="24" />
   6: </Style>

In this case, BigFontButton is “inheriting” its width and height from BigButton and its alignment from StandardButton.  When we assign this to Button3…

   1: <Button x:Name="Button3"
   2:         Content="Style: Big Font"
   3:         Style="{StaticResource BigFontButton}" />

The results are just what we hope for:

BasedOnStyles

DataValidation

The DataValidation demo is, if I’m honest, my favorite. I particularly like that this works by combining two existing parts of the Silverlight framework:

  • The ability to have the data object test a value and throw an exception if the value is invalid, which is turned into an error by the binding object and returned to the UI
  • The Visual State Manager which makes responding to that error either trivial or fall within a well established pattern.

Another thing I like about this feature is that you can and will use this long before you have a deep understanding of how it works.  That can be frustrating when you want to modify the behavior, but all the pieces of the puzzle are available, and here’s a road map to getting there.

First, Visual State and Templates

I would approach this by temporarily setting aside the issue of error handling and start with visual states and templates.  We have a series of videos that walk  you through this, and I’d view them in this order:

If you are serious about obtaining a deep understanding of all this, I’d also read the following mini-tutorials

With all that done, error handling will be almost self-evident.  The data entry classes have a new Visual State Group: ValidationStates that consists of three possible states

  • Valid
  • InvalidUnfocused
  • InvalidFocused

The sequence of events is that when the user attempts to enter data into one of the data entry objects (e.g., a TextBox) that data is transmitted to the DataBinding engine which asks the data object to which the TextBox is bound if the data is valid.

In the demo, we create a Book as a data object, and the book has an ISBN field.  We bind a TextBox to the ISBN field and when the user enters the ISBN the DataBinding object asks the book instance if the ISBN is valid.  The Book tests for three conditions:

  1. The data must be 10 characters long or it throws an exception with the exception message “Must be 10 characters long”
  2. The data must consist only of the numerals 0-9 or the letter X or it throws an exception with the exception message “must consist only of the numerals 0-9 or the letter X”
  3. The last character must match the checksum of the first 9 digits (the algorithm is described in Wikipedia) or it throws an exception with the exception message “checksum not valid.”

If you have set your flags properly (to be described in a minitutorial on data validation) the exception is turned into a command on the UI to change the visual state from Valid to either InvalidUnfocused or InvalidFocused.  What happens then is entirely up to whomever created the behavior for those visual states.

Rather than leaving you to your own devices, the controls team has provided default Visual State behavior for the following controls:

  • TextBox
  • CheckBox
  • RadioButton
  • ListBox
  • ComboBox

and in the next (post-beta version) PasswordBox

That behavior is to turn the control red, and when you click back in, to display the message from the exception,

InvalidChecksum

 

You are of course free to change all of this by templating this control just as you would any other (which is why you invested all that time reading about templating!)

Navigation

The final demo doesn’t exist. I just open up Visual Studio and create a new project clicking on Silverlight Navigation Application as shown in this cropped image,

NewNavProject

Visual Studio creates the infrastructure for you, opening with four Xaml files: MainPage.xaml and in the Views folder, AboutPage.xaml, ErrorWindow.xaml and HomePage.xaml.  Running the application (without touching it in any way) gives you a multi-page application ready to be customized to your needs.

NavigationWindow

More details to come on Navigation and especially on Validation. 

On The Bleeding Edge: Where All The Fun Is.


















Tim Heuer did a brilliant job in
his recent blog post sorting
through and summing up some of the confusion that has
arisen out of the current unusual circumstances of Silverlight,
Blend and Visual Studio all having two versions available at the same time: a release version and a pre-release version.

Rather than replicating his work, let me point you to his
post and also provide a slightly different perspective of life on the bleeding edge… 

 


Silverlight, Blend, Visual Studio, Oh My.

SilverlightLogo Silverlight 2 is a released development product available here 

Silverlight 3 is a beta product (with no commercial go live license) that is scheduled to go live this summer. It is available here.

Expression Blend 2 is the current commercial version of Expression Blend, available with full support (and on a trial basis if you like) here.  This supports Silverlight 2.

Blend 3 is in Preview mode and targets Silverlight 3, it is available on a trial basis here. To target Silverlight 2 you will want Blend 2 SP1.

VS2010 Visual Studio 2008 SP1 is the current and fully supported edition and it comes in many flavors: Standard, Professional, and Team System

Visual Studio 2010 Beta is ready for testing.

Windows Windows Vista is our current released operating system for individual computers, available here

Windows 7 Release Candidate is here and available for you to test

The Bottom Line

There are numerous mix and match variations, but why make yourself crazy? 

  • To target Silverlight 2, install Silverlight 2, Blend 2 and either VS 2008


  • To Target Silverlight 3:
    • Install Silverlight 3, Blend 3 and VS 2008 (Sp1) or
    • Install Silverlight 3, Blend 3 and VS 2010

NB: If you choose Visual Studio 2010 you will not be able to use the RIA Services at this time.

You can choose other combinations (e.g., Silverlight 2, Blend 2 and VS 2010, but unless you have good reason to, I don’t see the point. If you want the exhaustive list, however, see Tim’s post.

Please note that any time you are installing a Beta product you are on the bleeding edge and you must be prepared for less reliability than with a released product. Further, it is my personal belief that if you install a pre-release product you must also be prepared to repave your machine when you install the next version. It may not be needed, but being ready for it is a prudent precaution.

Pioneers take Risks But Achieve Great Things

Using pre-release software can certainly create headaches: when you run into a problem you must ask yourself: Is it Blend?  Visual Studio? Win7? Silverlight or me?   Aiiii!   But it is also the very best way to keep ahead of the learning curve, and each of these products, though pre-release is surprisingly stabile and each is well supported on their respective Microsoft sites:

My Working Environment on the Bleeding Edge

As a personal choice, I am currently keeping these working environments: 

Silverlight 2, Blend 2, Visual Studio 2008, Vista.

Silverlight 3, Blend 3, Visual Studio 2008, Windows 7.

Silverlight 3, Blend 3, Visual Studio 2010, Windows 7.

I do most of my work on the last of these, and so far it has been a gas.

Virtual Machines

As Tim correctly points out, one very powerful option when working with pre-release software is to use virtual machines – easily reset and recreated, but typically you pay a bit of a performance penalty.

I’m committed to Two Tool Development

I confess. After years of developing with separate debuggers, editors and compilers it was a wondrous thing to have an Integrated development environment in which all three and more were combined. I love Visual Studio.  And for the past year or so I imagined that Blend, while wonderful, was a temporary solution until Dev10 (shorthand for Visual Studio 2010) was ready.

Bzzzz. No! But thanks for playing!

After reviewing Dev10 (which is wonderful) and talking with the team, I’m now convinced that while many developers will do all their development in Visual Studio, serious (and certainly advanced) Silverlight programmers will in fact opt to work with two tools indefinitely.  It isn’t just that Blend is better suite for some types of work and VS for others; it is that there are real limitations (did I say that?); places where they do not overlap, and won’t any time soon.

For example, and taking this from the perspective of a developer; I’m thrilled that I can now create rows and columns in my grid in VS and that I can drag and drop controls on the design surface. That greatly simplifies the design process and while Blend may have some advantage there, only time will tell whether it is worth switching back and forth to accomplish these goals.

On the other hand, if I want to add animation I have two realistic choices: hand code it in Xaml in Visual Studio (always fun, might be dangerous, maybe tomorrow) or open Blend (where it just keeps getting easier).

Similarly, if I want to template a control (which, interestingly, I want to do more and more, especially as I work more with Data Validation), then once more Blend is not only the tool of choice, it is my only viable alternative: Visual Studio just isn’t designed to make that easy.

Coding In Blend

“Well,” I hear you say, “why go to VS at all? You can code right in Blend, with Intellisense and etc.”  Yah, you can. But as my buddy Dave Platt says (I’m cleaning this up) you can have an appendectomy through your mouth; it just takes longer and hurts more.  The ability to do bits of coding in Blend is a great convenience, but it wasn’t designed to be a programmer’s environment and there is no comparison between the level of support if offers and the level of support offered in Visual Studio. Not even close.  (OK, I owe you a list of specifics, but for now let’s take it as given).

That’s Not A Bug It’s A Feature

It is tempting to be somewhat defensive about this; almost as if this were a step backwards. But on reflection, I think it is actually a great leap forwards.  Rather than trying to make VS into an almost adequate designer, the folks who own Visual Studio decided to create a great developer tool. When you need to go beyond that, to take on relatively advanced design problems (such as managing view state and the associated story boards) it makes sense to use a tool that does that for a living.

And since the two tools work on the same project at the same time, with no need to “import” or “export” cycling between them is (nearly) painless.

Caveat: You Can’t Get There From Here (Yet)

While I strongly encourage you to create a machine with VS2010 (on Win7 if you can!) and with Blend 3, please note that as of this writing you can not open a Silverlight 3 project written for .NET 4 with the Blend 3 currently available (remember, we released Blend 3 back in March, years ago in web time).  To overcome this horrific limitation <smile>, you need only create a .NET 3.5 application. To do so, create a new solution, click on C# (or VB or Silverlight) and then drop down the framework and select ..Net Framework 3.5 as shown here,

Framework35

You’re back in business, though you will not for now be able to take advantage of the new .NET 4.0 framework features.

I will be returning to this theme of two-tools quite a bit, but wanted to open the door for discussion right away as I explore the myriad features in Silverlight 3.

Just Built My First SL3 / Dev 10 App

As you no doubt know we released Beta 1 of Visual Studio 2010 today   (the usual caution applies: I would advise only installing this on a machine you are prepared to repave!).  [Update - the Landing Page for all things related to VS 2010 Beta1 is here. ]

I installed it and Silverlight 3 on my laptop running Windows 7 (yowza!) and then fired it up and created an incredibly simple app as follows:

NewVS10Project

In the new project dialog shown cropped here, I chose to build to the latest version of the .NET Framework (marked Red-circle 1), then chose C# as the language I’d build in (2); narrowed the types of projects by choosing Silverlight (3) and finally chose a Silverlight application (4). 

At the bottom (not shown) I picked the directory and named the project Element Binding.

NewVS10ProjectDialog

 

 

As in previous versions, I’m prompted to choose either a web-based or a simple test application (I chose the latter) but I then had to choose to build to Silverlight 3 rather than 2).

VS10WhichVersion

Visual Studio opens on a new Silverlight 3 application and here is where everything changes.  No longer does the design surface say preview; now it says “Design” and means every syllable.  I created columns and rows much as I would in Blend (by clicking in the margins of the grid:

VS10CreatingColumns

I then dragged a slider into the first column and a text block into the second. WooHoo!

VS10DragControls

I then set the values for the slider to be 0 to 100 and the small increment to be 1 and the large increment to be 100. Finally, I set the properties for the TextBlock, the most important of which being its Text; which I set by clicking on the symbol next to Text (shown circled below) to choose Apply DataBinding

VS10ApplyDataBinding

The Source Dialog opens, and choosing ElementName brings up a list of the elements to which you can bind. Clicking on Slider1 (the slider control) caused the instruction “Use the Path pane to choose propoerties for the Source“ to appear as shown circled in the figure below,

VS10BindingToAnElement

Clicking on the Path pane opened a list of all of Slider’s properties. The property I wanted to bind to was Value, and I clicked on that. I had the option of choosing additional properties or options, but that was all I needed and in fact when I closed the dialog the value of the slider was immediately reflected in the text block in the designer. A quick test run of the application demonstrated that the TextBlock was now bound to the value of the slider, with no need for an event or an intervening data object! 

Sweet.

The application runs as intended,

VS10BoundElement

and here is the complete source, all of which is Xaml:

   1: <UserControl x:Class="ElementBinding.Page"
   2:    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   3:    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   4:    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
   5:    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
   6:    mc:Ignorable="d"
   7:    d:DesignHeight="100"
   8:    d:DesignWidth="200">
   9:    <Grid x:Name="LayoutRoot"
  10:          Background="White"
  11:          Height="62">
  12:       <Grid.RowDefinitions>
  13:          <RowDefinition Height="3*" />
  14:          <RowDefinition Height="1*" />
  15:       </Grid.RowDefinitions>
  16:       <Grid.ColumnDefinitions>
  17:          <ColumnDefinition Width="200*" />
  18:          <ColumnDefinition Width="200*" />
  19:       </Grid.ColumnDefinitions>
  20:       <Slider Height="22"
  21:               Margin="0,20,0,0"
  22:               Name="slider1"
  23:               VerticalAlignment="Top"
  24:               Maximum="100"
  25:               SmallChange="1"
  26:               Value="50"
  27:               LargeChange="10" />
  28:       <TextBlock Grid.Column="1"
  29:                  Height="21"
  30:                  HorizontalAlignment="Left"
  31:                  Margin="5,0,0,0"
  32:                  Name="textBlock1"
  33:                  Text="{Binding ElementName=slider1, Path=Value}"
  34:                  VerticalAlignment="Center"
  35:                  Width="95"
  36:                  FontFamily="Verdana"
  37:                  FontSize="18" />
  38:    </Grid>
  39: </UserControl>

 

The key new Silverlight 3 feature is found on line 53 where we bind directly to the Slider.

This is just too much fun.

ecq100

Example-Code Quality, GuaranteedThis code was compiled with Silverlight 3 (Beta) using Visual Studio 10 (Beta) on Windows 7 (RC).  For more on this guarantee, please see this page.

Time Flys Like An Arrow; Fruit Flies Like A Banana

We recently released my video on the new Animation Transition Control and in looking it over I noticed that I promised to follow up on the definition of a Date/Time “Tick”

Gregorian

A quick look at Wikipedia reveals any number of problems with attempting to count the number of nanoseconds from the date 1/1/01. Without diving too deep into this bit of trivia, I will note that the Gregorian calendar used in civil affairs (in which today is May 8, 2009 AD or CE) attempted to fix errors in the Julian calendar but missed the mark, and created problems of its own.  These were “corrected” a number of times, introducing new problems making it nearly impossible to historically find your way backwards with any exactitude through the middle ages (10 days were dropped from the calendar all in one go in some countries by Papal Bull, but not in other countries, and some parts of Europe did not adopt some aspects of the Gregorian calendar for another two hundred years, with the Swedish introducing February 30 (30!) in 1712). Greece didn’t make the switch until 1918, fully three centuries after Pope Gregory’s proclamation.

Complicating things further is the introduction of leap seconds for the past 40 years, to account for the accumulation of irregularities in the Earth’s rotation.

Rata Die

A little further research, however, puts this all to rest, as it turns out that the Rata Die (RD) system assigns numbers to calendar days independent of calendars, and is almost certainly what Microsoft uses for Ticks as RD counts forward from 1 at midnight on January 1, year 1  in the Proleptic Gregorain calendar (that is, the Gregorian calendar you produce by starting today and carrying the Gregorian calendar backwards in time past the years of its introduction). 

Wasn’t that fun?

This is a note that I’m Cindy To Buy Chocolate

Newton Remember the Newton?  Such a great idea… almost. Long before the iPhone, Apple released the Newton, promising that you could write in long hand and the Newton would turn your scrawl into printed words. Unfortunately,  not always the words you wrote. 

There was a wonderful posting on UseNet called “If Lincoln had a Newton” – a search turned up what I hope is a faithful copy which includes this excerpt:  “Newer are unseated in a greased civil wear, toasting wealthier that notion or andy otter nodding so conceptive and so detoxicated can loading ensure….”

Gary Trudeau ran a series of now famous strips about Doonesbury’s frustrated but tenacious loyalty to the almost-perfect technology.

NewtonDoonesbury
Doonesbury Aug. 27 1993

 

Yesterday: handwriting. Today: Voice

Today’s Newton is voice transcription services that do for dictation what the Newton did for handwriting. I’ve subscribed to Jott because it answers a real need: the ability to send myself a reminder (with an alarm at a specific time) when I think of something (or my wife tells me something) I need to remember, but I’m driving. My choice without Jott was between 

  • waiting until I could safely pull over and enter it into my iPhone by which time I would certainly have forgotten what I wanted to write down, not to mention where I was driving to or…
  • crashing and being killed in which case there is would be no point in remembering

With Jott I can just press 1 button, Jott answers and says “Jott what?”  I say “Reminder”, it beeps, I dictate, and that’s it. I’m done. No fuss, and at the designated time, it rings my phone and reminds me. Very cool.

Unfortunately, Jott offers a great deal more. I can add entries to my todo list or to my calendar. Worst of all,  I can send email.  And this is where things get ugly.  I sent my wife a test message. I dictated “Hi. This is a note that I’m sending to you by Jott it.”  Here’s the verification message:

image

You can almost see how it got from one to the other. It’s actually not that bad.  I’ve seen worse. On the same day actually.

Google bought my telephone service, Grand Central, which was and is a wonderful offering that rings all my phones when I get a call and lets me answer wherever I am.  Originally, if it took a message it used to send me an email with the phone number of the person who called. Now it transcribes their message and sends an SMS. Cool. Kinda. Yesterday I IM’d my friend Alex asking him if he had any graphics left over from our nascent company “Silverlight Consulting” AIM forwarded my message to his phone. He called back and left this message on Grand Central (now called Google Voice):  “Hey. You’re looking for Silverlight Consulting stuff, I probably have that. I’ll call you tonight. Alright. Ciao.” 

I received this:

googleVoice

Just Give Me A Hint

The technology is exciting, and I’m a cutting edge kind of guy… I’m willing to take a garbled message and reverse engineer what they must have said, but I do need a hint.

The trick of course is to pick and choose your usage, not to expect too much and to enjoy the humor in the situation. But caveat emptor; don’t leave a life and death message through telephone transcription just yet.

Validation. Hey! You’re Done!

 

Towards the end of my “What’s New In Silverlight 3” presentation for Tech Ed,  I discuss the (much anticipated) enhanced Data Validation in SL3.  Now, anyone who has been around the block a few times knows that there are a lot of different ways to handle data validation, and that each framework offers a different approach (not that long ago the approach was summed up as “hey, you’re a programmer, you want data validation, write some.”)

error1

error3

Plus Ca Change, plus c’est la meme chose

In October I wrote a blog entry about Data Validation in Silverlight 2.  It is interesting to look back at it now and realize that what has changed is not the use of the binding engine, setting the mode to two way, or even setting NotifyValidationError=true andValidationExceptions=true. All that was true back in October.

What has changed is that back in October, we wrote the code to manage everything about the validation – not only the business logic (which is to be expected and desired) but the entire UI for managing the error notification:


olderrorcode

From Hand Coded To Toolable Visual State


ValidationStates

The key innovation in Silverlight 3 is to tie error handling into the Visual State Management of the control. We are used to the fact that all the standard controls have two state groups: the CommonStates and the FocusStates. To these we now add three ValidationStates,

What is more, a number of input controls (TextBox, CheckBox, RadioButton, ListBox, ComboBox and soon PasswordBox) already have default storyboards for transitioning into these states (as you’ll see in just a moment

This means that right out of the box these controls know how to respond to invalid data, where the validity is determined by the object to which they are bound. Sweet.

Writing The Code

Let’s start simple, using the out-of-the-box capabilities, and then in a subsequent post I’ll look at how a little templating can give you much finer control over the interaction with the user.

To make this work you need the following:

  • A form with a way for the user to provide input (we’ll use a text box)
  • A data object to bind the input control  to
  • A user to enter incorrect data

Here is a picture of the form, displaying the error message that is caused by entering an invalid ISBN (one that has the right number of digits but where the checksum does not compute correctly):

checksumInvalid

We’ll support two other errors as well (not the right number of digits, and invalid values)

InvalidLength

invalidValues

Start With The Data

What I like most about this model is you start with the data, not the UI. You begin by designing your data object, and what validity checks you want.  I’ll post the code right after Tech-Ed, but I start with a Book class that implements INotifyPropertyChanged in the normal way. Then I added to the property for the ISBN my validation checking, throwing an exception if it is invalid in any way. The text I put in the exception is the text that shows up in the error message.  Here’s the ISBN10 property:

public string ISBN10
{
get
{
return isbn10;
}
set
{
if ( value.Length != 10 )
{
throw new ArgumentException( "Must be exactly 10 integers long" );
}

char[] isbnAsArray = value.ToCharArray();

foreach ( char c in isbnAsArray )
{
if ( ( !Char.IsNumber( c ) ) && c.ToString().ToUpper() != "X" )
{
throw new ArgumentException( "Must be numbers or letter X" );
}
}

int runningTotal = 0;
for ( int i = 0; i < 9; i++ )
{
int val = ( Convert.ToInt32( isbnAsArrayIdea.ToString() ) * ( 10 - i ) );
runningTotal += val;
}
int mod = runningTotal % 11;
int checkSum = 11 - mod;

int isbnCheckSum = -1;
if ( isbnAsArray[9].ToString().ToUpper() == "X" )
isbnCheckSum = 10;
else
isbnCheckSum = Convert.ToInt32( isbnAsArray[9].ToString() );

if ( isbnCheckSum != checkSum )
{
throw new ArgumentException( "Checksum is invalid!" );
}

isbn10 = value;
NotifyPropertyChanged( "ISBN10" );

}
}

[ Checksum computation from Wikipedia. ]

From Data To DataBinding

Once you’ve created your data object, you can build the UI around it, and bind the display objects to the properties of the data object. I decided to create the page in Blend, making it absurdly easy to lay out the rows and columns and to define the style for the prompt and for the data entry text box.

BlendValidation

I could have assigned the visual state, etc. inside Blend, but since I wasn’t changing anything, but rather just using what is already provided I saved this and clicked on Edit In Visual Studio. I then added the binding for the Title and Author by hand,

<TextBox x:Name="Title"
Grid.Column="1"
Grid.Row="1"
Text="{Binding Title}"
Style='{StaticResource Input}' />
<TextBox x:Name="Author"
Grid.Column="1"
Grid.Row="2"
Text="{Binding Author}"
Style='{StaticResource Input}' />

And followed that by adding the binding for the ISBN which required just a couple extra properties, but, you’ll notice, the same properties discussed in the October article and shown above,

<TextBox x:Name="ISBN10"
Grid.Column="1"
Grid.Row="3"
Style='{StaticResource Input}'>
<TextBox.Text>
<Binding Mode="TwoWay"
Path="ISBN10"
NotifyOnValidationError="True"
ValidatesOnExceptions="True" />
</TextBox.Text>
</TextBox>

That’s it! the rest just works.  No, really.

One Little Extra

Alright, if you want to get fancy; the text box doesn’t update and check the validity of its contents until you tab out (how else can it know when you’re done?). Cribbing from Karen Corby’s presentation at Mix I added a button to attach the UpdateSource() method of BindingExpression onto, and while I was at it, being amazingly lazy, I added a button that puts in the real ISBN for Death In Venice (one does get tired of typing the same thing while debugging!)

Here’s the Xaml,

<Button x:Name="FillButton"
Content="Fill Textbox With valid ISBN 10"
Width="200"
Height="25"
FontSize="14"
Grid.Column="0"
Grid.Row="4"
Margin="5"
HorizontalAlignment="Right" />

<Button x:Name="ValidateButton"
Content="Validate Now!"
Background="Green"
Width="120"
Height="25"
FontSize="14"
Grid.Column="1"
Grid.Row="4"
Margin="5"
HorizontalAlignment="Left" />

and here’s the code-behind for the buttons,

void ValidateButton_Click( object sender, RoutedEventArgs e )
{
// BindingExpression requires using System.Windows.Data
BindingExpression bindingExpression =
ISBN10.GetBindingExpression( TextBox.TextProperty );
bindingExpression.UpdateSource();
}

void FillButton_Click( object sender, RoutedEventArgs e )
{
ISBN10.Text = "0141181737";
}
womc900

This code was compiled with Silverlight 3 – Which is a beta product!  For more on this guarantee, please see this page.

Animated Visual State Transitions with the Transitioning Content Control

 

The Silverlight Toolkit is innovative in many ways, not least of which is that controls are released in one of four quality bands:

  • Mature: ready for release
  • Stable: suitable for most scenarios
  • Preview: suitable for most basic usage scenarios, may have moderate number of breaking changes as the control is developed.
  • Experimental: intended for evaluation purposes

The control I’ll be considering today was developed (and described here) by Ruurd Boeke and is currently in the Experimental band. You can expect that the API will change quite a bit, but that said, it is an enormously useful control right now; and thus I’ve submitted a video and this write-up.

What’s It For?

The goal of the Transitioning Content control is to make it easy to add animation when you are changing content within a control as demonstrated here. [You’ll need to click on DomainUpDown on the left (and surprisingly, not on TransitioningContent!) and Animations on top. The following cropped image illustrates where to click, but provides only a shadow of the impact

DemoTransition

Getting There In 3 Steps

To make this crystal clear, and to show how easy it really is to use this control, we’ll build the example three times: first with a Content Control, then with a Transitioning Content Control, and finally, adding data binding and the ability to transition more complex objects.

Starting Simple

Version 0 begins with a grid with two columns. The left column contains a ContentControl and the right a button. Here is the complete Xaml:

<UserControl x:Class="tccDemo.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="300" Height="150">
<StackPanel Background="Bisque">

<ContentControl x:Name="cc1"
Content="Click button to change."
HorizontalAlignment="Center"
Margin="20"
FontSize="18" />

<Button x:Name="doChange"
Content="Change"
Width="80"
Height="30"
HorizontalAlignment="Center"
FontSize="14"/>

</StackPanel>
</UserControl>

The job of the ContentControl is to hold a single piece of content: in this case a string. The button’s job is to cause that content to change, which we do programmatically in the button’s click event handler in MasterPage.xaml.cs, shown in full:

using System;
using System.Windows;
using System.Windows.Controls;

namespace tccDemo
{
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
doChange.Click += new RoutedEventHandler( doChange_Click );
}

void doChange_Click( object sender, RoutedEventArgs e )
{
Random random = new Random();
cc1.Content = random.NextDouble().ToString();
}
} // end class
} // end namespace

Each time the button is clicked, a new value is displayed.

For more on Skinnable Custom Controls, see the blog series that starts here, or consider these videos (click on the image to go to the video):

SkinnableCustomControlsPart1a SkinnableCustomControlsPart2a
SkinnableCustomControlsPart3 SkinnableCustomControlsPart4

Before we dive into the TransitioiningContent control and how it does its work, let’s look at how to use it. We start by replacing the ContentControl with a TransitioningContentControl, but to do this we need to add a reference to System.Windows.Controls.Layout.Toolkit in the references and a namespace to the top of the Xaml file

xmlns:layout="clr-namespace:System.Windows.Controls;
assembly=System.Windows.Controls.Layout.Toolkit"

With that in place we can modify MainPage.xaml to replace the ContentControl with the TransitioningContentControl and replace the Change button with two buttons: one for Up and one for down. Here is the complete Xaml:

<UserControl x:Class="tccDemo.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:layout="clr-namespace:System.Windows.Controls;
assembly=System.Windows.Controls.Layout.Toolkit"
Width="400" Height="200">
<StackPanel Background="Bisque">
<layout:TransitioningContentControl x:Name="tcc"
HorizontalAlignment="Center"
Margin="30"
FontSize="18"
Content="Click buttons to change content" />

<Button x:Name="UpButton"
Content="Up"
Width="100"
Height="30"
Margin="10"
FontSize="14"/>
<Button x:Name="DownButton"
Content="Down"
Width="100"
Height="30"
Margin="10"
FontSize="14"/>
</StackPanel>
</UserControl>

The code is modified only to set the Transition property of the TransitioningContentControl.  Here is the complete code behind file:

using System;
using System.Windows;
using System.Windows.Controls;

namespace tccDemo
{
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
UpButton.Click += new RoutedEventHandler( UpButton_Click );
DownButton.Click += new RoutedEventHandler( DownButton_Click );
}

void DownButton_Click( object sender, RoutedEventArgs e )
{
tcc.Transition = "DownTransition";
Random random = new Random();
tcc.Content = random.NextDouble().ToString();
}

void UpButton_Click( object sender, RoutedEventArgs e )
{
tcc.Transition = "UpTransition";
Random random = new Random();
tcc.Content = random.NextDouble().ToString();
}

}
}

Here is the effect:

Adding DataBinding and Objects

In both of the examples so far, the content has been a simple string. It is possible, however, to provide a more complex object, by modifying the TransitioningContentControl and using an explicit ContentTemplate.

<layout:TransitioningContentControl   
x:Name="tcc"
Margin="20"
FontSize="18"
HorizontalAlignment="Center"
Content="Use buttons...">
<layout:TransitioningContentControl.ContentTemplate>
<DataTemplate>
<StackPanel >
<TextBlock Text="{Binding Title }"
FontFamily="Georgia"
FontSize="14" />
<TextBlock Text="{Binding Author }"
FontFamily="Georgia"
FontSize="14" />
</StackPanel>
</DataTemplate>
</layout:TransitioningContentControl.ContentTemplate>
</layout:TransitioningContentControl>

This follows all the normal conventions of using a ContentTemplate. We fill it with a DataTemplate which holds a StackPanel, allowing us to place two TextBlocks, both of which use binding syntax to indicate that they are going to bind to the Title and Author properties of whatever object they are given, respectively.

The rest of the Xaml file is unchanged.

We need a data object, and so we create as simple a data object as possible to illustrate this idea; noting that of course you can get your data from a database, from an XML file, etc.  Here is the complete contents of Book.cs including the static property we’ll use to obtain some pre-created data,

using System.Collections.Generic;

namespace tccDemo
{
public class Book
{
public string Title { get; set; }
public string Author { get; set; }

public static List<Book> Books
{
get
{
List<Book> theBooks = new List<Book>();
theBooks.Add( new Book()
{ Title = "The Raw Shark Texts", Author = "Steven Hall" } );
theBooks.Add( new Book()
{ Title = "Columbine", Author = "Dave Cullen" } );
theBooks.Add( new Book()
{ Title = "Unfriendly Fire", Author = "Dr. Nathaniel Frank" } );
theBooks.Add( new Book()
{ Title = "The Inheritance", Author = "Dave Sanger" } );
theBooks.Add( new Book()
{ Title = "Sir Gawain and the Green Knight",
Author = "Simon Armitage" } );
theBooks.Add( new Book()
{ Title = "The Superorganism", Author = "Holldobler and Wilson" } );
return theBooks;
}
}
}
}

 

MainPage.xaml.cs is modified somewhat more significantly, to hold a membervariable of type List<Book> (thus avoiding having to “get” the data repeatedly) and a counter as a convenience so that we can cycle through our somewhat meager collection.  Here is the complete MainPage.xaml.cs

using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;

namespace tccDemo
{
public partial class MainPage : UserControl
{

private List<Book> books = Book.Books;
private int counter = 0;

public MainPage()
{
InitializeComponent();
tcc.Transition = "Normal";
tcc.Content = books[counter++];
UpButton.Click += new RoutedEventHandler( UpButton_Click );
DownButton.Click += new RoutedEventHandler( DownButton_Click );
}

void UpButton_Click( object sender, RoutedEventArgs e )
{
tcc.Transition = "UpTransition";
tcc.Content = GetBook();
}

void DownButton_Click( object sender, RoutedEventArgs e )
{
tcc.Transition = "DownTransition";
tcc.Content = GetBook();
}

public Book GetBook()
{
if ( ++counter >= books.Count )
counter = 0;
return books[counter];
}
}
}

The constructor sets the initial visual state to Normal and sets the content of the TransitioningContentControl to the first book in the collection. It then sets up the two event handlers. The job of each is to set the Transition state and then call the helper method that gets the next book in the collection.

Visual State Ambivalence

The TransitioningContent is a bit ambivalent about its visual states. There are four states that are hardwired into the control as it is currently written:

  • Default
  • Normal
  • UpTransition
  • DownTransition

However, if you examine the attributes at the top of the class (used to signal, for example, both the Visual State Manager and tools like Blend what visual states the class supports) you’ll find this:

[TemplateVisualState(GroupName = PresentationGroup, 
Name = NormalState)]
[TemplateVisualState(GroupName = PresentationGroup,
Name = DefaultTransitionState)]

[TemplatePart(Name = PreviousContentPresentationSitePartName,
Type = typeof(ContentControl))]
[TemplatePart(Name = CurrentContentPresentationSitePartName,
Type = typeof(ContentControl))]
public class TransitioningContentControl : ContentControl

There are precisely two visual states made visible to Blend and the VSM.  The net effect is that you can certainly use the UpTransition and DownTransition, but they were added as examples of how you can freely extend this class with any transitions you like.

Here’s how it works. The TransitioningContentControl consists of two parts both of type ContentControl: PreviousContentPresentationSitePartName and CurrentContentPresentationSitePartName. 

To add an animated transition from content A to content B you need only hand the two to this control and tell it, by passing in a string, what storyboard to invoke.  If you pass in the string TransitionUp or TransitionDown then it already knows what storyboard to invoke, as Ruurd Boeke wrote those and put them in the Resources section of TransitioningContentControl.xaml.  Here, for example, is his UpTransition:

<vsm:VisualState x:Name="UpTransition">
<Storyboard>
<DoubleAnimationUsingKeyFrames
BeginTime="00:00:00"
Storyboard.TargetName="CurrentContentPresentationSite"
Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/>
<SplineDoubleKeyFrame KeyTime="00:00:00.300" Value="1"/>
</DoubleAnimationUsingKeyFrames>

<DoubleAnimationUsingKeyFrames
BeginTime="00:00:00"
Storyboard.TargetName="CurrentContentPresentationSite"
Storyboard.TargetProperty="(UIElement.RenderTransform).
(TransformGroup.Children)[3].(TranslateTransform.Y)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="30"/>
<SplineDoubleKeyFrame KeyTime="00:00:00.300" Value="0"/>
</DoubleAnimationUsingKeyFrames>

<DoubleAnimationUsingKeyFrames
BeginTime="00:00:00"
Storyboard.TargetName="PreviousContentPresentationSite"
Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="1"/>
<SplineDoubleKeyFrame KeyTime="00:00:00.300" Value="0"/>
</DoubleAnimationUsingKeyFrames>

<DoubleAnimationUsingKeyFrames
BeginTime="00:00:00"
Storyboard.TargetName="PreviousContentPresentationSite"
Storyboard.TargetProperty="(UIElement.RenderTransform).
(TransformGroup.Children)[3].(TranslateTransform.Y)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/>
<SplineDoubleKeyFrame KeyTime="00:00:00.300" Value="-30"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</vsm:VisualState>

The effect of this is to target first the opacity of the current content, which will go from 0 to 1 over 3/10 of a second. During that same time period it will move up the Y axis from 30 to 0 (remember that the Y axis counts up as it moves down the screen).  In the second half of the animation the targetproperty is the opacity of the previous content which fades away from 1 to 0 over that same 3/10 of a second, while the content itself moves up from 0 to –30.

Notice that the storyboard is within the VisualState whose name is UpTransition.

The class itself has a public property named Transition:

/// <summary>
/// Gets or sets the name of the transition to use.
/// These correspond directly to the VisualStates inside
/// the PresentationStates group.
/// </summary>
public string Transition
{
get { return GetValue(TransitionProperty) as string; }
set { SetValue(TransitionProperty, value); }
}

This acts as a front for the Dependency Property which is registered immediately below

public static readonly DependencyProperty TransitionProperty =
DependencyProperty.Register(
"Transition",
typeof(string),
typeof(TransitioningContentControl),
new PropertyMetadata(OnTransitionPropertyChanged));

A quick review of the Silverlight documentation reveals the meaning of each of the four parameters:

DPRegister

Notice that the type of the TransitionProperty is string, and parenthetically, notice that the final parameter, typeMetadata,  is explicitly noted for usage with a PropertyChangedCallback, which is what is done here.

OnTransitionPropertyChanged is overloaded in the implementation, but the net effect is to set the source of the content control and to set the string representing the new transition and then to call ChangeTransition whose job is to make sure it is safe to set a new transition, and then to obtain the PresentationState Visual State group and then to look to see if there is a state for the string passed in. If so, that transition is set as the new value for the transition.

Thus, with this somewhat unusual control,  you can modify the visual states within the PresentationGroup) without subclassing, and by doing so (and providing a storyboard) you can add any transition you like, which you can then invoke by passing in its name!

Caveat! As noted earlier, this control is in the experimental band, and this API is very likely to change.

I hope you found this bit of control spelunking as interesting as I did sorting it out; and it is just fine to set all of the details aside and just use the control in conjunction with other controls to create animated transitions without over-worrying about how it is doing its magic.

The State of Things – A Brief Review Before Tech Ed.

I think it is fair to say that interest in Silverlight is wicked-high.

  • Twitter grades. Jesse: 99.5th percentile; Tim: 99.8th percentile!
  • Between us Feedburner shows more than 10,000 subscribers
  • 31 Silverlight Sessions at Mix, 30 at Tech Ed
  • LiveSearch of “Silverlight” returns 450 million pages
  • Amazon lists over 500 books on the topic!

And with all of that comes a very serious responsibility on our part to meet the needs both of new Silverlight programmers and those of you who’ve been with us since hieroglyphics.  My goal: how can we increase the immediate and long term utility of the information we’re providing?

More Useful Information Through Listening

It starts by shutting up and listening (admittedly not my strong suit).

We’ve been taking every opportunity to speak world wide at industry gatherings large and not so large.  While I’m blasted to be presenting at Tech Ed, it is also true that community and regional events like Code Mash  can be CodeMashLogoterrific opportunities to talk to programmers who I might not get as much of a chance to sit down with at the larger shows.

At this year’s Mix I skipped a number of presentations to spend more time in the Third Place, and no surprise it was time incredibly well spent. I’ve been sitting in on Ask the Expert Sessions, spending more time on Twitter, Facebook and other social networks and generally finding that developers are more than eager to let us know what they need, if only we’ll be quiet enough to listen. And respond.

Last year, about this time the community asked for more end-to-end projects. Thus were born numerous innovations, most notable of which is Tim’s Application Corner and, more recently, my ongoing glass-window design and coding of a VideoWiki. 

I’m extremely happy to say that the VideoWiki project will benefit from the assistance and collaboration of a number of extraordinary people both inside and outside of Microsoft.

Even as we speak I am working actively with that most gifted of Animation and development/design experts, Jeff Paries.  We will soon blog our rough design ideas, and then walk through the decision processes, the creation of wireframes and more. But I digress.

More Useful Information Through Innovation

signalNoise While our How Do I videos remain extremely popular, some folks would rather read than watch; and thus was born both the Silverlight Tutorials, but also my experiment in writing mini-tutorials within my blog, and here my ego takes over and I must show off that  while my Twittalyzer scores are generally pathetic, my Signal to Noise ratio just hit 100%! – as promised: More signal, Less noise.

Better Information Through Intensive Collaboration

Tim and I are teaming up with Laurence Moroney and many others inside Microsoft,  transcending false internal “boundaries” and creating collaboration across organizations. That model is proving out not only with Evangelists, but also with developers; more and more we are crossing old lines and creating new and effective virtual teams.  (Do I get points for not saying syn**gy?)

Better Performance Through Recognizing How Much Is Left To Be Done

Before we get too happy with ourselves, there is much more to do on all these fronts (and many more); but folks at Silverlight.net (and our sister sites) are very committed as are, as you know by their incredible productivity, the teams writing the code.

What’s On Deck?

My own list, just of material I hope to provide in the next few months, is staggering. The number of topics for my blog, VideoWiki, videos, tutorials, book, and presentations is a wonderful and absurd and magnificent shot of main-line enthusiasm and I can safely report to you, after nearly two years into my one year stint at Microsoft, that I’ve barely begun. 

jesseSigColorMatchForBlog

Tomorrow’s blog entry: Transition Content Control.
This week: Next step in the WiKi Design

Next