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.

Posted in z Silverlight Archives | Comments Off on Just Built My First SL3 / Dev 10 App

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?

Posted in z Silverlight Archives | Comments Off on Time Flys Like An Arrow; Fruit Flies Like A Banana

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.

Posted in z Silverlight Archives | Comments Off on This is a note that I’m Cindy To Buy Chocolate

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( isbnAsArray.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.

Posted in z Silverlight Archives | Comments Off on Validation. Hey! You’re Done!

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.

Posted in z Silverlight Archives | Tagged , | 2 Comments

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

Posted in z Silverlight Archives | Comments Off on The State of Things – A Brief Review Before Tech Ed.

Easing is… Easier

For those who have been wondering “Where’s Jesse??” the answer is that I’ve been head’s down preparing for my presentation at Tech Ed (you are going to Tech Ed aren’t you?!) 

Microsoft has three major conferences. The following is my personal description:

PDC – What is coming in the next few years. The BIG conference.
Tech Ed – What is the current state of the art. – Dive deep with geeks
Mix – Let’s get developers and designers together and create magic.

I have not abandoned any of my other projects; and all will be ramped back up to full speed as soon as my presentation is ready.  In the meantime, this entry is a brief exploration of Easing in Silverlight 3 and Blend 3.

A Note About Reduced Blogging
It’s hard cutting down on blogging. I’ve been experience  sweating, malaise,  chills and compulsive scratching.  Hmmm….

 

In Silverlight 2, Easing Wasn’t Obvious

One aspect of animation that has always looked more difficult than it really is, is easing

First, the term itself is a bit intimidating to those of us who are not specialists: what exactly is being eased?  Second, it is usually introduced like this: “oh, and then you can double click on the animation and adjust the easing. Drag the yellow dots until the easing gives you the effect you want…

The problem of course is that this presupposes that you know what easing is and what effect you want.  Happily, Silverlight 3 and Blend 3 make all of this much more straight forward.

What Are We Trying To Do?

First, let’s get the fundamentals straight:

  • Easing is a term of art for modifying an animation so that the rate of change is not uniform: specifically so that you can introduce acceleration or deceleration
  • In refers to easing at the start of the animation
  • Out refers to easing at the end of the animation

Straight Line Acceleration

Step 1 might be to create an animation that moves a dot from a starting point to an ending point over 1 second.

The animation engine is going to divide the distance it has to move the dot over the one second you’ve allocated.  The effect is that the dot moves smoothly and at the same speed from beginning to end.

Its speed is uniform.  However, (and don’t panic!)  what we care about is not just speed but acceleration.

Without setting the easing your acceleration is, essentially infinite; the object moves from 0 to its uniform velocity in zero time. Unfortunately, things don’t do that in the real world.

 

 

 

 

 

 

 

Changing the Rate of Acceleration

We are used to the Newtonian laws of physics if only intuitively. Imagine watching a movie in which an old fashioned steam engine railroad is shown.  If it went from standing at the station, emitting steam, passengers embarking and the conductor calling out “’Board!” to 60 MPH with no acceleration we’d fall over laughing.  We have fully incorporated the assumption that the train will start out painfully slowly, building speed as it goes.

This is true of everything in our environment, and adding even a little bit of acceleration or deceleration can provide a subtle, even unconscious verisimilitude to animation that moves your animated effect from cartoon like to professional.

And there’s the rub: in Silverlight 2 this felt like the province of designers and other professionals who knew what they were doing with those tiny yellow dots and funny curves. 

Silverlight 3 Makes It Easy, and Teaches What It Is Doing

In Silverlight 3 you can still create your own hand-drawn easing, but the common easing functions have been created already. Instead of leaving you with a line and a graph to draw the line on, the new easing setting lets you pick the curve you’d like. That, and a quick translation of what these curves mean, and suddenly all the mystery disappears.

The first thing to notice is that you can just click on the easing you want (Back, Bounce, Circle, Cubic) and within each you have your choice of one of three modes (In, Out, In/Out).

Now, about those nasty curves….

Easing Is A Function

Easing is accomplished by a (usually) simple function. It works like this: the acceleration (or deceleration) will change as a function of time.  That means, as time passes, the acceleration will increase.

With no easing the function looks like this:

You read that the function of time is equal to time, or in English: the acceleration will increase uniformly over time.

With that, it is easy to go to the CubicEase

 

Thus after three units of time passes, you should see 9 times the acceleration. You would expect that if you had a cubic easing at the beginning of the animation (In mode) that you’d see a fairly radical bend upwards in the curve. Consider what happens to f(t) as t goes from 1 to 5 (shown in the small table on the right)

You can see the radical bend in the curve shown in the graph in the help files (excerpt in image below)
and in the drop-down in Blend (above)

An Example To Bring It Home

To see this at work, I created an example that lets you pick from a few different easing functions and to set any of the three modes. Let’s take a quick look at the surprisingly straight forward code.  The following is the complete Xaml,

<UserControl x:Class="EasingChoices.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="400"
Height="500">

<!– I’ve divided my page into an upper part for the animation
and a lower part for the controls. –>

  <Grid x:Name="OuterGrid"
Background="Bisque">
<Grid.RowDefinitions>
<RowDefinition Height="3*" />
<RowDefinition Height="2*" />
</Grid.RowDefinitions>

<!-- One storyboard and its animation.
Note that the animation is given a name as we’ll address it programmatically. -->
<StackPanel x:Name="LayoutRoot"
Background="White"
Grid.Row="0">
<StackPanel.Resources>
<Storyboard x:Name="myStoryboard">
<DoubleAnimation x:Name="theAnimation"
From="0"
To="200"
Duration="00:00:3"
Storyboard.TargetName="myRectangle"
Storyboard.TargetProperty="Height">
</DoubleAnimation>
</Storyboard>
</StackPanel.Resources>

<!--The object we'll be animating-->
<Rectangle x:Name="myRectangle"
Fill="Blue"
Width="200"
Height="30" />
</StackPanel>

<!--The inner grid holds the radio buttons-->
<Grid x:Name="innerGrid"
ShowGridLines="False"
Grid.Row="1 ">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="3*" />
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>

<!—First of two stack panels-->

<StackPanel Grid.Column="1">
<RadioButton x:Name="Bounce"
GroupName="Easing"
Content="Bounce"
HorizontalAlignment="Left"
VerticalAlignment="Center"
IsChecked="True"
Margin="10"
FontSize="18" />
<RadioButton x:Name="Sine"
GroupName="Easing"
Content="Sine"
HorizontalAlignment="Left"
VerticalAlignment="Center"
IsChecked="False"
Margin="10"
FontSize="18" />
<RadioButton x:Name="Power"
GroupName="Easing"
Content="Power"
HorizontalAlignment="Left"
VerticalAlignment="Center"
IsChecked="False"
Margin="10"
FontSize="18" />
</StackPanel>

<!--Second stack panel-->
<StackPanel Grid.Column="2">
<RadioButton x:Name="In"
GroupName="Mode"
Content="In"
HorizontalAlignment="Left"
VerticalAlignment="Center"
IsChecked="True"
Margin="10"
FontSize="18" />
<RadioButton x:Name="Out"
GroupName="Mode"
Content="Out"
HorizontalAlignment="Left"
VerticalAlignment="Center"
IsChecked="False"
Margin="10"
FontSize="18" />
<RadioButton x:Name="InOut"
GroupName="Mode"
Content="In/Out"
HorizontalAlignment="Left"
VerticalAlignment="Center"
IsChecked="False"
Margin="10"
FontSize="18" />
</StackPanel>
</Grid>
</Grid>
</UserControl>

The supporting code responds to any button being checked by creating a new EasingFunction and telling the animation to use our new function rather than the one that appears in the Xaml.  To do this we take advantage of the fact that all the easing functions (BounceEase, SineEase, etc.) derive from a common base class: EasingFunctionBase.

using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Animation;

namespace EasingChoices
{
public partial class MainPage : UserControl
{
EasingFunctionBase easingFunction = null;

public MainPage()
{
InitializeComponent();

// all events call same handler
Bounce.Checked += new RoutedEventHandler( CreateNewEasingFunction );
Power.Checked += new RoutedEventHandler( CreateNewEasingFunction );
Sine.Checked += new RoutedEventHandler( CreateNewEasingFunction );
In.Checked += new RoutedEventHandler( CreateNewEasingFunction );
Out.Checked += new RoutedEventHandler( CreateNewEasingFunction );
InOut.Checked += new RoutedEventHandler( CreateNewEasingFunction );
}



private void CreateNewEasingFunction(object sender, RoutedEventArgs e)
{
if ( Bounce.IsChecked == true )
easingFunction = new BounceEase();
if (Sine.IsChecked == true )
easingFunction = new SineEase();
if ( Power.IsChecked == true )
easingFunction = new PowerEase();

if ( In.IsChecked == true )
easingFunction.EasingMode = EasingMode.EaseIn;
if ( Out.IsChecked == true )
easingFunction.EasingMode = EasingMode.EaseOut;
if ( InOut.IsChecked == true )
easingFunction.EasingMode = EasingMode.EaseInOut;

theAnimation.EasingFunction = easingFunction;
myStoryboard.Begin();
}
}
}

That’s it.  Set the easing sub-type, set the mode, assign to theAnimation’s EasingFunction and run the storyboard. Piece of pie.

Exercise for the reader:  Want to take this a step further? Determine which Easing functions would benefit from additional arguments (e.g., number of bounces), add UI to gather the values, and pass them in to the object.
Posted in z Silverlight Archives | Comments Off on Easing is… Easier

A Twitter App I want

Whose tweets do the people whose tweets I value, value?

That is, this application would help me find the people whose tweets I consistently value, and then find out whose tweets they consistently value, and it would do it in a reasonably anonymous way. (One can immediately imagine extending this to news groups and then books, music….)

[This RFC is the result of brief musings with John Papa who is not responsible for my corruption of it, but who is a great person to bounce ideas off of]

The Client

Here’s how it works… a client (Windows, Mac, Phone, iPhone, etc.) is created that lets me rank tweets on a scale of –3 to +3, with an unranked tweet scoring 0.

 

 

These ratings are sent to a web service where they are tied to my username but it is not possible for anyone but me to find out my rankings. (I might use my own rankings for culling my lists, discovering that there are people I follow whose tweets I don’t value very much).

Finding People To Follow

The next step is that I can ask the system for the top N valued by my top X.  The restriction is that both N and X must be a multiple of 5. That is, I can ask the system for the top 10 valued by my top 20.  The system will then examine the rankings of my top 20 and combine them to create a list of the 10 names most highly valued by those 20.

It will then return something like this:

Your top twenty ranked the following people in their top ten. They are not in order,  but they are shown as the top 5 and the second 5.

 

Friendly Name @Name # Tweets last 3 months Halves
George @GeorgeW 238 1
JohnA @JohnAdams 12 1
Tom @TJefferson 40 1
JQ @JohnQ 10 1
AJ @AndrewJ 2 1
JMonroe @JamesM 38 2
MVB @MartinVanB 32 2
JT @JohnTaylor 45 2
Millie @MillardF 101 2
Bucky @JamesB 23 2

 

This indicates that overall your top twenty found all of these ten to be in their most highly ranked group, but the group in the first half were ranked more highly than the group in the second half. If you ask for 10 that may not matter much, but if you ask for 50, having 10 groups of 5 can be a good compromise between the false precision of an ordered list and a totally random grouping.

If no one builds this by the time I finish ViKi perhaps this will make a good 2nd project.

Posted in z Silverlight Archives | Tagged , | Comments Off on A Twitter App I want

The State of the ViKi

In my previous posting about the VideoWiki project I mentioned that I fell off the edge of the world when I tried to replicate the work I had done previously with the player emitted by Encoder.  I’m told by the team that this is very much a work in progress, so I don’t want to get bogged down in the details, but let’s take a look at some of the issues that came up and where the code sits today.

The version of Expression Encoder that I used (version 2 service pack 1, version 2.1.1216.0) created the Template solution which in turn contained four projects

Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2008
Project(“{<GUID>}”) = “Template”, “Template.csproj”, “{<GUID>}”
EndProject
Project(“{<GUID>}”) = “MediaPlayer”, “MediaPlayer\MediaPlayer.csproj”, “{<GUID>}”
EndProject
Project(“{<GUID>}”) = “AdaptiveStreaming”, “AdaptiveStreaming\AdaptiveStreaming.csproj”, “{<GUID>}”
EndProject
Project(“{<GUID>}”) = “ExpressionPlayer”, “ExpressionPlayer\ExpressionPlayer.csproj”, “{<GUID>}”
EndProject

Our working project on the other hand, is, for now,  a single project solution named Viki-Start) consisting of MainPage.xaml/.cs, App.xaml/.cs and a Views directory with the default three pair of files: AboutPage.xml/.cs, ErrorWindow.xaml/.cs and HomePage.xaml/.cs as well as the usual Properties, Resources, Bin, etc. folders.

Having templated ExpressionPlayer in Blend, we copy ExpressionPlayer.dll, MediaPlayer.dll and AdaptiveStreaming.dll into the bin/debug folder of Viki-Start and add them to the references of the project and we update App.xaml in Viki-start with the template that we created in blend (that is, in Template/App.xaml) being careful about namespaces.

What You Think You Did and What You Really Did

Twenty years ago I learned a good bit of close up magic. What I really liked about it was showing a trick and then listening to the person I showed it to describe what I did to someone else. What they saw was not what I did.  For the past three days, I’ve been insisting to everyone, including myself, that in all the previous videos and tutorials, it worked perfectly fine to call MediaPlayer from within my project but now it changed with Silverlight 3. Wrong!  Going back to find the original code so that I could point out the differences, there are none. Looking at the tutorial and the videos closely, I always launched the project from the html file – which worked then and works now; it is just that now I no longer want to do that; I want to launch from within the program.

What changed was not the ExchangePlayer (well, actually, it did change, but not in a way that affects this discussion) but my requirements.  This is a lesson I have to keep learning: synchronicity is the bane of debugging. It is the error of post-hoc ergo prompter hoc (just because it broke after I moved to Silverlight 3 doesn’t mean the failure had anything to do with moving to Silverlight 3.).

My Current Hack

Sometimes, even if you know you will eventually throw it away, it is worth getting the code to work; if only to understand it in pieces. Here is how I got my code to work.  When you ask encoder to create your starter application (which you’ll remember we then templated in Blend) it emits an entire project as shown above (Template.sln).  The two files we most care about are ExpressionPlayerControl.cs and MediaPlayer.cs.

ExpressionPlayerControl is the control that we are actually templating.  Its job is to display our media clip and raise an event when our markers are hit and it does so by inheriting from MediaPlayer and by creating a custom media stream source for adaptive streaming.  In fact, the point of ExpressionPlayerControl is to extend the MediaPlayer to fully support Adaptive Streaming.

OnStartup

The idiom for feeding the source videos to a MediaPlayer (or an ExpressionPlayer) is to call OnStartup passing in the event arguments obtained from the html page that invoked the program.  Assumptions are made. For example, the initial URI is created by obtaining the URI of the html page.

Uri uriStockContent = HtmlPage.Document.DocumentUri;

That value is then modified if there is a play list (which in my case there always was) in this section

if (e.InitParams.TryGetValue("playlist", out strInitValue))
{
try
{
Playlist.Clear();
Playlist.ParseXml(HtmlPage.Document.DocumentUri, strInitValue);
}

and we’re off to the races.  The supporting code for PlayList is defined in the PlayListCollection class of MediaPLayer and PlayList itself is a dependency property defined to be of type PlayListCollection.

A key assumption built into MediaPlayer is that ParseXml expects a document to serve as the source URI of the media items – that is, the physical location of the document must be the same as the physical location of the videos.

 

When Is A MediaPlayer Not A MediaPlayer?

If you look  up ParseXml in the Silverlight documentation for MediaPlayer you won’t find it. That is because the MediaPlayer that is listed in the documentation is not a Silverlight control, it is, rather, a player to run media using Silveright in an ASP.NET Web Page and is not the MediaPlayer emitted by Encoder.  Same name, different beast. 

My Temporary WorkAround

To get the application up and running for now, I overloaded OnStartup in ExpressionPlayer and in MediaPlayer and then copied the modified DLLs (along with the unmodified DLL for AdaptiveStreaming) into Viki-Start.

  // ExpressionPlayer 
public void OnStartup()
{
base.OnStartup();
Uri whereAmI = HtmlPage.Document.DocumentUri;
string pathAsString = whereAmI.ToString();
int offset = pathAsString.IndexOf( "TestPage.html" );
string stub = pathAsString.Substring( 0, offset );
Playlist.Clear();
PlaylistItem pli = new PlaylistItem();
pli.MediaUrl = new Uri( stub + "/encoded.wmv" );
pli.IsAdaptiveStreaming = false;
pli.ThumbSource = stub + "/test.jpg";
pli.Title = "Encoded Video";
pli.Description = "Hardcoded Hypervideo";
Playlist.Add( pli );
}
// MediaPlayer
public virtual void OnStartup()
{
Playlist.Clear();
m_autoPlayCache = true;
m_autoLoadCache = true;
m_mutedCache = false;
m_stretchMode = Stretch.None;
UserBackgroundColor = new SolidColorBrush( ColorFromString( "#FF0000FF" ) );
DisplayTimeCode = false;
CaptionsVisibility = Visibility.Collapsed;
}

 

Not beautiful, but sufficient to keep the project moving.

     Previous  ViKi Version 0.0.01
 

 

Posted in z Silverlight Archives | Tagged | Comments Off on The State of the ViKi

Making a good posting GREAT

 

An example of the difference between an “ok”  blog post and a brilliant posting  crossed my reader yesterday and it was too canonical not to comment on. 

Scott Hanselman wrote about his wish (shared by so many of us) for a way to signal to tech support that we’re clued in, without sounding obnoxious.  

In short, his suggestion is that you say a magic word (“fizzbin”) as a signal that you know what you are talking about thus saving everyone a lot of time.

My point however, is that his article can be used as an object lesson in what makes a good post great, and, fortuitously, you can see the difference in this case by drawing a line where a competent blogger might have stopped writing. Had he done so, Scott woud have had a perfectly respectable posting, but by adding a short dialog, his posting went from “ok” to instant classsic. Here is a brief excerpt:

Fizzbin

(This image is cropped and the red was added by me)

Click here for the full postin.

I believe that it is the dialog, and especially the geek-familiarity Scott implies with the final line (“sweet!”)  that really nails it.

 

Great post.

 

Posted in z Silverlight Archives | Comments Off on Making a good posting GREAT

ViKi Version 0.0.01

It is of course inertia, that overwhelming sense of “what is the most important thing to do first?” that will kill you, and this project got hit bad because it came just when Passover interrupted my normal schedule, along with the usual slew of unusual events, such as preparing for TechEd (ah, I’ve another month, what, me worry?)

So, believing strongly that the first thing to do is something I’m going to take my own advice and start building; not where the most important lessons are, but where the low hanging fruit is: by creating a hyperVideo application in Silverlight 3 that will accomplish the following:

  • Get something going
  • Force the issue of where this project lives and how I track the code
  • Give me something concrete to improve
  • Start us right off with media
  • Force the issue of how does a user even follow this project without Silverlight 3 installed (I think I have a good answer for that)

How Do You Follow This Tutorial If You Don’t Have Silverlight 3?

hourglassOfProgrammersLet me be clear, Microsoft’s position  is that Silverlight 3 is a developer only product, currently in Beta with no announced release date. Thus,  we will continue to support and to provide lots of learning material for Silverlight 2.  That said, this site in general and my blog in particular seems to attract an hourglass shaped demographic

Thus, I feel fairly safe assuming that a large proportion of readers of this blog have (or will soon have) set up a computer with a Silverlight 3 development environment. That said, I will try to put in images as well as live streaming examples so that you can follow this project even if you do not yet have a computer or virtual machine with Silverlight 3 installed.

 

 

Version 0.0.01

 

Nothing gets me started like starting. I opened a new project and chose Silverlight Navigation Application from the Templates section and C# from the Project types

 

While I believe in being bi-lingual C# and VB, I usually start in C# if given the opportunity. I will provide VB code for this entire project, however, either translations of tricky parts, or complete working code periodically.

 

This opened a very pretty navigation page which I proceeded to make ugly by opening Blend 3 and modifying in a few ways (changing the BrandingTextNormalStyle, BrandingTextHighlightStyle adnd  the PageLink style as well as the border margins and sizes, to suit my personal aesthetics

Modified Navigation Styles

PageSwitchingThis will serve as the framework in which we will build the ViKi player, instantly rendering my videos on multi-page applications quaintly obsolete.

 HyperVideoPart1

 

 

The key to getting started with the ViKi project, however, lies with a different set of videos; the 3 part series that begins here  and which we will adapt as the starting point for the ViKi.

 

 

 

 

The First Thing We Need Is A Video

It would be helpful if we were all looking at the same video, and it would be even more helpful if that video was

  • short so that we don’t have to shlep around inside a huge file and
  • about a topic that we won’t confuse with the ViKi project itself

I am going to download Element to Element Binding because it is just under 6 minutes and has nothing to do with Hypervideo.  Since I want to have a marker every 20 seconds, (a somewhat arbitrary decision) this video will end up with about 18 markers.  I chose every 20 seconds as I see that as being about the right compromise between having as many opportunities for markers as possible without exceeding human reaction time.

To create this for yourself, download the video, place it into encoder, put a marker at 20 seconds and every 20 seconds after (naming each marker sequentially (marker-01, marker-02, etc.) and then instruct Encoder to give you a Silverlight Standard player as discussed in the Hypervideo videos!

 

Encoding

The image has been cropped, but you can see that we’ve placed a marker every 20 seconds and named them sequentially from Marker1 to Marker 21.

Emitting The Player

 

With the video and markers in place, it is time to ask Encoder to emit a player for us (far easier than creating one by hand!). To do so, click on the OutputTab (not shown in illustration above), choose the Silverlight 2 Default template and modify the output name to add the word Encoded as shown below,

EncoderOutputForHypervideo

 

 

 

Click on the encode button at the bottom of Encoder, and just a few moments later you not only have an encoded video, but much more impressively you have a player ready to display your new hypervideo.

(All of this is reviewed in great detail in the 3 videos and the series of blog entries on Hypervideo  that begin here – we’re really just catching up here as a starting point on the ViKi project). 

As you may remember, the next step is to click on the white dot next to the template name and ask to edit the project in Blend, where you will name your new template, build the project and then edit the a copy of the player template (please see the referenced blog entries for step by step directions)

After you save the template in Blend, return to encoder, encode the video and return to your new project. Copy the styles from the app.xaml from the encoded project into the app.xaml for your new project (combining them). 

Then copy MediaPlayer.dll and ExpressionPlayer.dll from the Encoder-emitted player project into the bin/debug directory of your new project.  Add a reference to each in your project and then add a namespace to the top of your HomePage.xaml,

xmlns:ExpressionPlayer=”clr-namespace:ExpressionMediaPlayer;assembly=ExpressionPlayer”

 

The Home Page

We’ll place the player inside the Home page much as we placed in inside page.xaml in the previous examples,

<navigation:Page x:Class="ViKi_0._0._01.HomePage" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
xmlns:ExpressionPlayer="clr-namespace:ExpressionMediaPlayer;assembly=ExpressionPlayer"
Title="HomePage Page">
<Grid x:Name="LayoutRoot" Background="White">
<Grid.RowDefinitions>
<RowDefinition Height="9*" />
<RowDefinition Height="0.5*" />
</Grid.RowDefinitions>
<ExpressionPlayer:ExpressionPlayer
Margin="0,0,0,0"
x:Name="myPlayer"
Style="{StaticResource ExpressionPlayerStyle1}"
Grid.Row="0" />
<TextBlock x:Name="Message"
Grid.Row="1" />
</Grid>
</navigation:Page>

Falling off the Rails

It was about here that I fell off the rails.  I thought  I’d grab the code that I’d written and demonstrated a dozen times and just plunk it down into the home page. “not so fast” the gods yelled. I then spent 14 hours looking at (a) how ExpressionPlayer had changed and why it worked perfectly when its parameters were passed from an html file but not at all when they were passed from my code.

I spent a good part of the next day getting it to work, and along the way learning a good bit about how the code emitted by encoder has changed (for the better) and why, and what it means to working with that code. I also learned a good bit about working with URIs, media and all sorts of digressions that will come in handy. I will write that story tomorrow.

The following 2 severely cropped images will give a sense of the working code as it stands today,

 ViKi0001.1
The “home” page with the templated and modified Expression player playing the hypervideo we encoded and responding to the marker at 20 seconds.

 

ViKi0001.2

   The about page with an accordion from the Toolkit serving to provide information about the project.

 

All the code and a detailed walkthrough to follow.

 

  Previous: VideoWikiDesign Step 1      Next State of the project
 
 
 
 

Powered by VisualSVN!

Posted in z Silverlight Archives | Comments Off on ViKi Version 0.0.01

VideoWiki Design Step 1

 

The initial approach to designing the VideoWiki is to layout all the obvious pieces of the design, understanding that this will evolve over time.  Here is my first cut at the design.  

If you have Silverlight 3 installed, the following is the live interactive outline, otherwise, below is a snapshot of the outline as an image,

OutlineImage1 OutlineImage2 OutlineImage3

While this lays out the topics I hope to cover in the next six months or so, it says nothing about schedule, or how to illustrate these topics or even how these topics relate directly to the VideoWiki (with some obvious exceptions. But it is a start; it is, to harken back to yesterday’s analogy, stimulus applied to overcome the axon hillock.

 

                                      Previous VideoWiki Step 0   Next Version 0.0.01

Posted in z Silverlight Archives | 1 Comment