Jason Cooke works as a software tester for the AppFx group at Microsoft, where he's has been responsible for testing the Calendar and DatePicker controls.

 

One feature that I wanted in the Calendar control for Silverlight 2 was cool transition effects, where changing the visible days/months/years would kick off some neat animation. That feature did not make it in, but I've been working on a hack that uses the Silverlight templating model to add new functionality. You can view the results at http://jrcooke.members.winisp.net/share/SlidingCalendarDemo/default.htm.

By handling the loaded event in the templates for the CalendarButton and CalendarDayButton, an app can graft an additional helper class (in this case SlidingCalendarHelper) on top of the existing Calendar control and change its behaviors.

 

To get this functionality in your Silverlight application:

(Please note that this code is provided under the Microsoft Public License and is also provided "as is", without warranty of any kind.)

 

1.       Download the SlidingCalendar project from http://jrcooke.members.winisp.net/share/SlidingCalendar.zip.

2.       Add the SlidingCalendar project to your solution.

3.       In your page, add an event handler like this:

private void CalendarButtonLoaded(object sender, RoutedEventArgs e)

{

    double transitionSeconds = 1.0;

    bool spin = true;

    SlidingCalendar.SlidingCalendarHelper.AddButton(

        (DependencyObject)sender, transitionSeconds, spin);

}

4.       Retemplate your CalendarButton and CalendarDayButtons so each of their root Grid controls hook up their Loaded event to the CalendarButtonLoaded handler. (If you are already templating your controls, just add in the event handler code.)

5.       Test it out!

Change the values of the local variables the method to change how fast the transition occurs and if the buttons spin.

 

How it works:

When you call SlidingCalendarHelper's AddButton method, it walks up the visual tree to determine which calendar holds the button. The method sets up dummy versions of each day, month, and year button, and puts them in their own grids, to mimic what the real buttons look like. It also binds to the data context of the real buttons, so that the dummy versions to be updated the real values change.

There are two types of transitions supported:

1.       Moving from one mode to another (for example, from the month mode to the year mode),

2.       Moving from one range of dates to another within a particular mode.

At the start of both types of transitions, the state of the calendar's previous set of buttons is duplicated in dummy buttons, which are moved into the location previously occupied by the real buttons. The real buttons are moved outside of the calendar in a staging position, and the myDoubleAnimation1 animation is started at 0.

As the animation moves from 0 to 1, the dummy buttons are moved out of the way, while the real buttons are brought into their correct location. When moving from one date range to another, the movement is just sliding the buttons around under the calendar. When changing modes, the buttons expand or shrink.

 

Known Issues

It probably goes without saying, but this code is provided under the Microsoft Public License and is also provided "as is", without warranty of any kind. In particular, I know of a few issues that, being a tester, it is hard for me to ignore:

1.       Ideally, the buttons would be clipped to a region completely within the grid region of the calendar. However, when changing from mode to mode, the buttons move over the Calendar header region.

2.       When changing months or modes before the previous transition finishes, the buttons can sometimes get stuck in an intermediate state.

3.       The animations eat up a lot of the CPU. It should be more performant.

4.       Dummy buttons don't always look right then the buttons are using a custom template. This indicates that the code for creating the dummy buttons is missing something.

I hope that you find this code useful!

 

Enjoy your programming,

Jason

 

 <Editorial Comment>

It's been crazy the past few months leading up to MIX.  I'll have a lot of great stuff to post soon ^_~ . In the mean time, I hope you all enjoyed Jason's post. Thank you Jason!

</Editorial Comment>