Page view counter

March 2009 - Posts

Quick 3-d Update

I mentioned in a previous blog post that I'd posted a two part video on the new 3d capabilities in Silverlight 3. Since then I've had a few great conversations with Jeff Paries (who knows more about Silverlight Animation than most people on the planet) and I had the opportunity to think about other, perhaps even better ways to accomplish the same thing.

This has led me to re-focus my next tutorial (forthcoming) on how 3d Animation can be used to add real value to an application (as opposed to making a great demo or a cool but not very useful bit of sizzle).

In the meantime, I did want to point you to Jeff's latest blog post on using Silverlight 3's perspective 3d, in which he flips a playing card through two planes and along the way explores some of the finer points of managing (for example) bit-map drop-shadow effects in a perspective transform.

In the small world department, Jeff begins his article by pointing to Corey Schuman's excellent summary of the fundamentals.  Now, Corey and I met only recently, but he is amazingly talented and enthusiastic, and he and I will co-author  Programming Silverlight 3  (which is something I should be shouting from the rooftops.)

 

The key change that I did go back and make to my demo code shown in the video (not required, but cleaner) is to remove the code that moves the "back" of the panel in and out of position using a translate transform and replaced it with a change of the visibility:

 

Revised Storyboard

<Storyboard x:Name="FlipFrontToBack">
     <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="FormFront"
                    Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationY)">
          <EasingDoubleKeyFrame KeyTime="00:00:00" Value="0"/>
          <EasingDoubleKeyFrame KeyTime="00:00:01" Value="90"/>
     </DoubleAnimationUsingKeyFrames>
     <ObjectAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="FormFront"
                    Storyboard.TargetProperty="(UIElement.Visibility)">
          <DiscreteObjectKeyFrame KeyTime="00:00:00">
                <DiscreteObjectKeyFrame.Value>
                     <Visibility>Visible</Visibility>
                </DiscreteObjectKeyFrame.Value>
          </DiscreteObjectKeyFrame>
          <DiscreteObjectKeyFrame KeyTime="00:00:01">
                <DiscreteObjectKeyFrame.Value>
                     <Visibility>Collapsed</Visibility>
                </DiscreteObjectKeyFrame.Value>
          </DiscreteObjectKeyFrame>
     </ObjectAnimationUsingKeyFrames>
     <ObjectAnimationUsingKeyFrames BeginTime="00:00:00"
                 Storyboard.TargetName="FormBack" Storyboard.TargetProperty="(UIElement.Visibility)">
          <DiscreteObjectKeyFrame KeyTime="00:00:00">
                <DiscreteObjectKeyFrame.Value>
                     <Visibility>Collapsed</Visibility>
                </DiscreteObjectKeyFrame.Value>
          </DiscreteObjectKeyFrame>
          <DiscreteObjectKeyFrame KeyTime="00:00:01">
                <DiscreteObjectKeyFrame.Value>
                     <Visibility>Visible</Visibility>
                </DiscreteObjectKeyFrame.Value>
          </DiscreteObjectKeyFrame>
     </ObjectAnimationUsingKeyFrames>
     <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="FormBack"
                   Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationY)">
          <EasingDoubleKeyFrame KeyTime="00:00:01" Value="270"/>
          <EasingDoubleKeyFrame KeyTime="00:00:02" Value="360"/>
     </DoubleAnimationUsingKeyFrames>
</Storyboard>

Anger

For those who find complex Xaml tedious to read, here it is in pseudocode:

< Create a storyboard named "FlipFrontToBack">     
<The first object to target is the stackpanel FormFront />
<change the RotationY property of the PlaneProjection >
<When we begin the angle will be 0/>
<One second later the angle will be 90/>
<Also target the visibility property />
<As soon as we start, set it to visible />
<At one second, set it to collapsed />
<We're done with formFront now let's do the FormBack />
<Start by setting its visibility to collapsed />
<At 1 second change its visibility to visible />
<Also change PlaneProjection.RotationY>
<At one second we'll set its angle to 270/>
<One second later the angle will be 360/>
<we're done />

Not so bad that way.

 
 

Bottom line, we're still doing our slight of hand when the front panel is at 90 degrees, but instead of bringing in the back panel from offstage, we just swap visibility, which means no matter how big you make your browser you won't see the man behind the curtain.

The code to go with the new tutorial will build on this a bit.



 

Previous: Update on Video Source Code


 

This work is licensed under a Creative Commons Attribution By license.
Posted by jesseliberty | 2 comment(s)
Filed under: , ,

Toolkit Control – TimePicker

 

 

 

You can learn a great deal about the new TimePicker class with a fairly simple example program that I will lay out and zip through here (a full video on the topic is coming very soon).

ClickOnGetStartedTo begin, you’ll want to download the latest Silverlight Toolkit, which you can easily do by  clicking on Get Started in the left margin of my blog (or on the image to the left) and from our Get Started page, click on number 4, Download Silverlight Toolkit.

That will bring you to the Codeplex home of the Toolkit where you can download any or all of the controls, the source to the controls, and/or the samples for Silverlight 2 or 3.  To get the latest controls, click on the menu item Releases, and then download either or both of the installers.

 

 

ToolkitDownload

The installer will place the libraries in the right location and make adding the resources to your application a snap.

 

Recreating The Example

Create a new Silverlight application (Silverlight 2 or 3) named TimePicker and add two resources: Windows.Controls and Windows.Controls.Input.Toolkit

AddRef

Add a name in the Xaml for “input” and let Intellisense help you choose System.Windows.Controls.Input.Toolkit”.  Set up a grid with five rows and three columns, as shown here,

<UserControl x:Class="TimePickerBlogSL3.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:input=
"clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Input.Toolkit
"
    Width="800" Height="200">
   <Grid x:Name="LayoutRoot"
         Background="White">
      <Grid.RowDefinitions>
         <RowDefinition Height="1*" />
         <RowDefinition Height="1*" />
         <RowDefinition Height="1*" />
         <RowDefinition Height="1*" />
         <RowDefinition Height="1*" />
      </Grid.RowDefinitions>
      <Grid.ColumnDefinitions>
         <ColumnDefinition Width="3*" />
         <ColumnDefinition Width="2*" />
         <ColumnDefinition Width="2*" />
      </Grid.ColumnDefinitions>

 

Our goal now is to add a Time picker and to allow the user to set the PopupButtonMode (do you click on the picker or hover over it to make it open) and the PopUp (RangeTimePicker or ListTime). 

ListTime looks like this

popuptime

 

RangeTimePicker looks like this:

 

RangePickerTime

Be Careful with Seconds

To add an interesting twist, the RangeTime popup optionally allows you to set the seconds while the Listtime does not, though it does allow you to set the number of minutes between each interval. (For example, I can set the interval to 7 minutes, and the ListTime changes accordingly, as shown in the next image)

7Minutes

Getting Started

With the grid iin place, let’s add a very simple TimePicker control to get started,

 

<input:TimePicker x:Name="FirstTP"
                  Width="200"
                  Grid.Row="0"
                  Grid.Column="0"
                  Margin="5"
                  HorizontalAlignment="Left"
                  VerticalAlignment="Center" />

Run the program. That’s it, you’re done. Works great.

Of course, it would be good to get the value from the time picker (you know, just to show we can).  To satisfy the cynics, we’ll add a prompt in the second column and display the value in the third,

<TextBlock x:Name="TimePrompt"
Text="Time:"
FontSize="18"
VerticalAlignment="Bottom"
HorizontalAlignment="Right"
Margin="5"
Grid.Row="0"
Grid.Column="1"/>
<TextBlock x:Name="Time"
FontSize="18"
Foreground="Red"
VerticalAlignment="Bottom"
HorizontalAlignment="Right"
Margin="5"
Grid.Row="0"
Grid.Column="2" />

There are two ways to get the value from the time picker into the “Time” textblock.

In Silverlight 2 (and optionally in Silverlight 3) you can respond to the DropDownClosed event that will fire when the user makes the time selection and the popup window closes

FirstTP.DropDownClosed += 
new RoutedPropertyChangedEventHandler<bool>( FirstTP_DropDownClosed );


void FirstTP_DropDownClosed(
object sender,
RoutedPropertyChangedEventArgs<bool> e )
{
Time.Text = FirstTP.Value.ToString();
}

Element Binding

In Silverlight 3 you can eliminate this event and handler and instead data bind the text element directly to the value of the TimePicker element as shown in this video and illustrated here,

<TextBlock x:Name="Time"
  FontSize="18"
  Foreground="Red"
  Text="{Binding Value, Mode=OneWay, ElementName=FirstTP}"
  VerticalAlignment="Bottom"
  HorizontalAlignment="Right"
  Margin="5"
  Grid.Row="0"
  Grid.Column="2" />

Setting the Mode and Type

We’ll let the user choose the mode and  popup type with radio buttons,

<!--Pop up mode-->
<TextBlock x:Name="PopupModePrompt"
Text="Style:"
FontSize="18"
VerticalAlignment="Bottom"
HorizontalAlignment="Right"
Margin="0,0,5,0"
Grid.Row="1"
Grid.Column="1" />
<StackPanel x:Name="PopUpModeStackPanel"
Orientation="Horizontal"
Grid.Row="1"
Grid.Column="2"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch">
<RadioButton x:Name="PopUpModeClickRB"
GroupName="PopUpMode"
Content="Click"
Width="Auto"
Height="Auto"
VerticalAlignment="Bottom"
HorizontalAlignment="Left"
Margin="10,0,0,0"
FontFamily="Georgia"
FontSize="18"
IsChecked="true" />
<RadioButton x:Name="PopUUpModeHoverRB"
GroupName="PopUpMode"
Content="Hover"
Width="Auto"
Height="Auto"
VerticalAlignment="Bottom"
HorizontalAlignment="Left"
Margin="10,0,0,0"
FontFamily="Georgia"
FontSize="18" />
</StackPanel>

(I won’t take the space here to show the PopUpBoxPrompt and radio buttons except to point out that they will be on Row 3 and otherwise very similar to the above.)

Optional Input Fields

Rows 2 and 4 are reserved for the input for the “Interval” (which is visible only when the user chooses Popup) and the UseSeconds checkbox (which is visible only when the user chooses RangePicker.) In the following illustration all are visible, a condition that is never seen in the wild,

 

4Rows

We want to display MinutesInterval when the user clicks on Pop Up and hide that and display Use Seconds when the user selects Range Picker.

 

 

 

The only tricky part is that while it is perfectly safe (if meaningless) to have an interval when using the RangePicker, an exception will be thrown if the TimePicker’s PopupTimeSelectionMode is set to AllowSecondsSelection and the TimePicker’s Popup is of type ListTimePickerPopup, so this must be carefully avoided. The place you typically run into this is when the user changes to RangePicker, selects UseSeconds, and then switches back to Popup. So we need to be just a bit careful.

 

Opening Vs. Opened

Like many controls, the TimePicker fires four events related to opening and closing its drop down (there does seem to have been some debate about whether it is a drop down or a pop up!)

  • DropDownOpening
  • DropDownOpened
  • DropDownClosing
  • DropDownClosed

That gives us exactly the level of control we need.

void FirstTP_DropDownOpening(
   object sender,
   RoutedPropertyChangingEventArgs<bool> e )
{
   SetMinutesInterval();
   SetSeconds();
}

We will check (and set) the interval and most important whether we are allowing seconds just before we open the chosen popup (dropdown) and thus when it is certain which one is wanted.

Sequence of Events

the sequence of events, then, is that we present the time picker on the left and two sets of radio buttons on the right, defaulting to Pop Up. We also present a text box in which the user can fill in the Minutes Interval (which we default to 15),

TimePickerStep1

 

When the page is loaded the constructor runs in which we assign to the value of the Time Picker the current time. We also set the event handlers and the initial PopupMode and PopUpType based on reading which radio buttons are checked (in this case, the radio buttons were set in the Xaml).

 

 

 
The Constructor
public MainPage()
{
InitializeComponent();

// initialzie the value to the current time
FirstTP.Value = DateTime.Now;

// radio button event handlers
PopUUpModeHoverRB.Checked +=
new RoutedEventHandler( PopUpMode_Change );
PopUpModeClickRB.Checked +=
new RoutedEventHandler( PopUpMode_Change );
PopupRB.Checked +=
new RoutedEventHandler( PopUpBox_Change );
RangePickerRB.Checked +=
new RoutedEventHandler( PopUpBox_Change );

// time picker event handlers
FirstTP.DropDownOpening +=
new RoutedPropertyChangingEventHandler<bool>(
FirstTP_DropDownOpening );
FirstTP.DropDownClosed +=
new RoutedPropertyChangedEventHandler<bool>(
FirstTP_DropDownClosed );
FirstTP.DropDownOpened +=
new RoutedPropertyChangedEventHandler<bool>(
FirstTP_DropDownOpened );

// set initial modes
SetPopUpMode();
SetPopUpType();
}

At the end of the constructor we call both SetPopupMode (click vs. hover) and SetPopupType (popup vs. range)

private void SetPopUpMode()
{

   // radio buttons are nullable booleans,  check for true
   if (PopUUpModeHoverRB.IsChecked == true)
   {
      FirstTP.PopupButtonMode = ClickMode.Hover;
   }
   else
   {
      FirstTP.PopupButtonMode = ClickMode.Press;
   }
}

SetPopUpType is very similar, but here we also set the visibility of the mutually exclusive user input fields (time interval or number of seconds)

private void SetPopUpType()
{
bool range = RangePickerRB.IsChecked == true;
UseSecondsCB.Visibility = range ? Visibility.Visible : Visibility.Collapsed;
UseSecondsPrompt.Visibility = range ? Visibility.Visible : Visibility.Collapsed;
TimeMinutesIntervalPrompt.Visibility = range ? Visibility.Collapsed : Visibility.Visible;
MinutesInterval.Visibility = range ? Visibility.Collapsed : Visibility.Visible;
   // old c programmer habit, same as if (range == true) for non-nullable bool   
if (range)
{
FirstTP.Popup = new RangeTimePickerPopup();
}
else
{
FirstTP.Popup = new ListTimePickerPopup();
}
}

The construct in the second through fourth lines is the C# ternary operator. You read this line

UseSecondsCB.Visibility = range ? Visibility.Visible : Visibility.Collapsed;

like this:  “if range is true, set UseSeconds.CB’s Visibility property to the enumerated value Visibility.Visible, otherwise set it to the enumerated value Visibility.Collapsed.” 

More generally, you can write

<type> <identifier> = <bool> ? <true> : <false>;

That is, test the boolean and assign the true value to the identifier if the bool evaluates true, otherwise assign the false value.  A simpler example would be

string nickname = IsOver18? “buddy” : “kid”;

which will set the string variable nickname to “buddy” if IsOver18 is true and will set it to “kid” otherwise.

 

Implementing DropDownOpening

As noted above, each time the drop down is opened we call the two methods that set one of the two mutually exclusive states, paying particular attention to the seconds.

void FirstTP_DropDownOpening( 
object sender,
RoutedPropertyChangingEventArgs<bool> e )
{
SetMinutesInterval();
SetSeconds();
}

SetMinutesInterval checks to see if the text box has something in it, and if so it converts that value to an int (ignoring the bulletproofing of testing for invalid values) and then assigns that value to the PopUpMinutesInterval of the timePicker. If the textbox has no value in it, the value is set to 10.  We don’t bother checking to see why type of Popup the user has chosen because there is no harm or foul in setting this when it isn’t used.

private void SetMinutesInterval()
{
if (MinutesInterval.Text.Length > 0)
{
// need try block here!
FirstTP.PopupMinutesInterval =
Convert.ToInt32( MinutesInterval.Text );
}
else
{
FirstTP.PopupMinutesInterval = 10;
}

}

 

SetSeconds has to be a bit more cautious because, as noted, an exception will be thrown if you set the TimePicker’s PopupTimeSelectionMode to AllowSeconds when the Popup type is not RangeChecker. In fact, (at the risk of saying this one more time)  the reason we’ve created this method is to ensure that we’re testing at exactly the last possible moment when the user can no longer change this mode!

 

private void SetSeconds()
{
if (RangePickerRB.IsChecked == true &&
UseSecondsCB.IsChecked == true)
{
FirstTP.PopupTimeSelectionMode =
PopupTimeSelectionMode.AllowSecondsSelection;
FirstTP.Format = new LongTimeFormat();
}
else
{
FirstTP.PopupTimeSelectionMode =
PopupTimeSelectionMode.HoursAndMinutesOnly;
FirstTP.Format = new ShortTimeFormat();
}
}

We only set the PopupTimeSelectionMode to AllowSecondsSelection if two things are true. First, it must be true that the user has requested a RangePicker and second the user has to have checked the checkbox indicating to use seconds,

 

UseSecondsCB

 

While it causes an exception to use seconds with a Popup picker, it is optional to use seconds with a RangePicker and the RangePicker works fine either way as shown below,

 

 

 

 

 

 

RangePickerNoSecondsRangePickerSeconds

 

Adding Formatting

A final touch that is a good example of where small things make a big difference, is that we change the Format property of the TimePicker if we are using second from ShortTimeFormat to LongTimeFormat, and thus show the seconds. You see this in the SetSeconds method, above,

 

FirstTP.PopupTimeSelectionMode = 
PopupTimeSelectionMode.AllowSecondsSelection;
FirstTP.Format = new LongTimeFormat();

Rather than post a complete project (which would require having one for Silverlight 2 and one for Silverlight 3, I’ve opted to post only the xaml and xaml.cs files. For Silverlight3 just copy the Xaml to MasterPage.xaml and for Silverlight to copy to Page.xaml. Be sure to fix up the Namespace names and to add the two references.  The source code is here.

 
 
Posted by jesseliberty | 7 comment(s)
Filed under: ,

On Email and Organization

Some people are naturally organized – my wife can (literally) find a receipt from five years ago within minutes. I’m lucky if I can find a receipt from Mix.

HEEEEEEEELP! (serie)

Organization Through Larger Boxes

I recently read a book that suggested that people like me have a tendency to try to deal with chaos by using smaller and smaller compartments and containers, when what we should do is use bigger boxes: stop trying for fine adjustments that you’ll only give up on and toss everything in; then find it when you need it. After all you add a lot more often than you retrieve (particularly true with computers where searching is easy and fast).

Which is why I’ve come to love Evernote

Thus, it was obvious once Scott H. pointed out that he gets by on 5 email folders, and zero automatic rules that my system of 250 subfolders (some four levels deep!) and about 60 rules (with categories and flags) was a recapitulation of the exact same problem.

So now, (after carefully archiving and backing up my existing system) I have the following folders:

  • Inbox
  • Act
  • Waiting
  • Reference
  • To Archive

Touch Things Once

That same book urged that you try hard to touch each piece of paper once (rather than open the envelope, put it aside, then put it in the to be paid, then pay it and put it in the paid to be filed, then file it, etc.) 

Each e-mail item goes to one of the folders above. It only goes to waiting if it is waiting for someone else. Everything in Act gets flagged with a due date. Everything in Waiting gets flagged with a reminder date.  Reference is for things I’m pretty sure I’ll need for a blog, video or tutorial in the near term, and auto-archives in six weeks in case I’m wrong.

The “To Archive” folder is really trash for those of us who are afraid to throw anything away.  Fortunately, 500Gig hard drives are small and inexpensive. I recently bought six. 

That’s it.

I’ll let you know how it works out.

Please feel free to leave comments, your email stories and arm-chair diagnoses below.

Mix 09 Trip Report

 

It is traditional when you return from a conference to file a "trip report" with your team. What follows is my trip report to you, with an emphasis on what I learned. I will not review, here, all that was discussed about what is new in Silverlight 3, that will come in many postings, videos, etc, but rather I'll try to report on how the conference affected my own plans for increasing your satisfaction both with Silverlight 2 and with Silverlight 3. 

I have to start, however, by saying that the excitement at Mix was palpable, and the reception was highly enthusiastic, first to Bill Buxton’s extraordinary “Back to the Future” keynote and then to the Gu’s amazing, mind-boggling presentation of all that we were rolling out.  The twittersphere could barely keep up, and the excitement persisted throughout the conference.

keynote2

Plans Arising Directly out of Mix

Speaking personally, as is often the case, much of the value occurred in the halls; in the interpersonal connections and in listening to what folks had to say: what was exciting, frustrating, enticing, meeting or missing expectations.

In addition, as I thought about my role and how to meet my goals for the next six to nine months, it became clear that two adjustments would be critical: more collaboration and more context.  The great news was that Mix also afforded the opportunity to set both in motion.

I'll explain what I'm doing about collaboration here, and I'll follow with what I'm doing about context within a couple days.

Collaboration

colaab
(image cropped)

One of the truly remarkable things about the Mix conference is how amazingly open and eager to collaborate people are. I had only to suggest the idea and people were ready to sign up….

    • Jeff Paries (Senior Digital Media Designer at Waggener Edstrom) a true expert will work with me on animation
    • Who could be better than John Papa to work with on Data
    • The founders of colaab – an incredible application they built from scratch entirely in Silverlight that I believe may ultimately be the killer app in RIA are willing to share some of what they've learned as object lessons in real world Silvelright
    • I'll continue to work with Justin Angel and the Toolkit team to keep you up to date on what they're bringing forward
    • I'll be working with Microsoft team members with expertise in Blend and related products to focus on how these tools can be put to use by developers
    • And the list keeps growing

Silverlight 2 and Silverlight 3

RequiredVersion As you know, Silverlight 3 is a Beta product with no Go Live license.

We are not going to be so infatuated with the latest and greatest that we stop providing world class information on Silverlight 2.

We'll try to find the right balance, and as Silverlight 3 moves towards release we will increase the time we spend on it so that you'll be completely ready.

As you may know, my book Programming Silverlight 2 has been cancelled, but I'm happy to announce that we O'Reilly has committed to shipping Programming Silverlight 3 with Visual Studio 2010 -- this year and I am committed to making it be one of the best books on the market. My co-author will be Corey Shuman.

Lessons we might learn from this year’s Mix

Finally, there are always a few things that can be improved or lessons to be learned. Here are my three observations on that note,

  • Wi-Fi availability was excellent within the conference, but less so throughout the hotel. A lot of us begin to itch if we are away from email for more than an hour or so.
  • Post-conference shut-down: It would be great if the "third place" could stay open for a couple hours after the final session so folks could unwind together and get their last minute questions answered.  If not, next conference, we'll have to set up a place to fall back to.
  • Predictable Availability: From now on, I intend to make myself predictably available in the equivalent of the third place. I very much enjoyed the informal contacts and discussions and look forward to this as a crucial part of upcoming conferences.

This work is licensed under a Creative Commons Attribution By license.

Photo Essay of Mix09

I’ve put together a very small photo essay of my trip to Mix, proving to myself (again) that phone cameras are incredibly convenient, and incredibly limited.

Collage

All in all, it was a blast.

Posted by jesseliberty | 2 comment(s)
Filed under: ,

Silverlight Toolkit Release

 

Easily lost among all the exciting announcements here at Mix is some great news about the Silverlight Toolkit. 

First, the March 2009 release for both Silverlight 2 and Silverlight 3 is now available here

This release includes six new controls:

The first two are covered in this video, the DomainUpDown in this second video, and the remaining three will be covered in videos I’ll be recording very soon.

You’ll also find that the Toolkit Team has been hard at work creating live examples on the CodePlex site,

 

Truly great.

Posted by jesseliberty | 4 comment(s)
Filed under: ,

Update on Video Source Code

Update on Video Source Code

First, thanks for your patience. I’m happy to confirm that the source code for Element to Element Binding and Using 3d are all correct for the Beta release. In addition, we’ll be posting the source code for Part 1 of Using 3d today as well.

ElementBinding

Element to Element Binding

3dPart1

Using 3-d Part 1

3d Part 2

Using 3-d Part 2

 


Timer Input

There was a very minor change to the enumeration for showing seconds used in the Timer control and we are uploading the revised code for that video immediately,

Timer

Timer Input Control

 


Domain Up/Down

The DomainUpDown control requires two minor changes. First, you’ll want to allow just a bit more room in the Xaml for the control,

image

Domain Up Down Control

<StackPanel x:Name="AirportStackPanel"
   Grid.Row="3"
   Grid.Column="0"
   VerticalAlignment="Stretch"
   Margin="0,10,-0.25,0"
   Grid.RowSpan="2">
    <ContentControl Content="Airport List"
          Style='{StaticResource Header}' />
    <StackPanel x:Name="DomainUpDownPanel"
      VerticalAlignment="Stretch"
      Background="#aa000000"
      Height="89">
       <input:DomainUpDown x:Name="AirportUpDown"
                 ItemsSource="{Binding}"
                 Height="90">
<input:DomainUpDown.ItemTemplate>
 
 
Be sure to compile your Toolkit controls against the appropriate Toolkit library (for Silverlight 2 or for Silverlight 3).  The code is unchanged, the API is unchanged, but you must choose the correct set of APIs. 
 
More about where the Toolkit libraries are now stored in my next post.

Previous: Compiling the Silverlight 3 Video Code                 Next Quick 3-d Update

Posted by jesseliberty | 2 comment(s)
Filed under: ,

Compiling the Silverlight 3 Video’s Code

As of this morning I have uploaded five videos (with C# and VB source code) for Silverlight 3.  To have this ready at the moment of release I opted for most to build with pre-beta code. This note will review what to do if you run into trouble making the code work (and if it is a problem I’ll quickly rebuild with the release Beta code).

ElementBinding

Element to Element Binding 

3dPart1

Using 3-d Part 1

3d Part 2

Using 3-d Part 2

Timer

Timer Input Control

 

These were  all built with just-pre-Beta source and should present no trouble at all.  I will double check them today and if there is a problem I’ll post how to fix and I’ll replace the code immediately.

image

Domain Up Down Control

 

This control was actually built with using Silverlight 2. We’ll have both  C# and VB Silverlight 3 examples posted as quickly as possible. 

Toolkit Control User Interface

It is always possible that between the time we create the video and the time the Toolkit control is released, the dev team will decide to “reskin” the control. That is the wonderful thing about “lookless” controls.  The good news is that the API and functionality is unchanged, and you can reskin them yourselves as well, as explained, for example, in the thread starting here

Posted by jesseliberty | 3 comment(s)
Filed under: ,

Let’s Talk Silverlight At Mix!

MixLogo1

There are a lot of presentations about Silverlight scheduled for Mix, and most of them look like they’ll blow the doors off; but we all know that some of the most fun and interesting things at any conference happen between sessions.

This year, I hope to have the opportunity to talk with a lot more folks in small groups, and so…

Making 3rd Place A Silverlight Place

pokerfaceTo create a little predictability,  I’ll try to be in “3rd Place”  (Marcello 4403) Tuesday through Friday from 4:30 to 6pm.

I’ll have my laptops, and when I’m not discussing Silverlight (or whatever else is on your mind), I’ll be blogging, coding or just listening to the new songs my daughter gave me.

 

 

 

 

 

 

Blogging and Twittering

twittermix

I’ll also be “reporting” from Mix via this blog and a blizzard of Tweets 

Click the little guy on the bench to subscribe to this blog; and the bluebird to Follow Me on Twitter.

subscribe followme

NB: All of my blogging about Mix will be tagged Mix09.

 

 

 

Photos

colab It is my hope to take a lot of photos at Mix and to post them on Flikr – stay tuned for details.





(If you don’t know who these guys are… you want to!)

 

  

  

My Schedule

I’ve posted my daily schedule, but Mix can be very dynamic and plans change quickly.

  Keep in touch and I hope to see you there!

-Jesse

(Yikes! It’s 9:30 10:30, and I have videos to finish)

Posted by jesseliberty | 2 comment(s)
Filed under:

An Hour Being Flexible

 

You never know where you'll end up discussing Silverlight…

TheFlexShow

I recently had the extraordinary opportunity to spend an hour talking about Silverlight with Jeffry Houser and John Wilker on The Flex Show (my part starts 4 1/2 minutes into the show, which you can listen to here).  It was great fun, and they couldn't have been more welcoming.


This work is licensed under a Creative Commons Attribution By license.
Posted by jesseliberty | with no comments
Filed under: , ,

Sparkling Client Podcast on The Bubble Chart

SparklingClientLogo

I'm very pleased to provide this link to a brief discussion with Erik Mork about the Bubble Chart from the Silverlight Toolkit, which I believe ties in nicely with this post from late December.

 

BubbleChart 
[Bubble chart from the most recent samples, slightly modified]

                [ Previous Podcast on the Silverlight Toolkit ]

      Previous: 1 Chart - Three Axes         Next: Podcast


This work is licensed under a Creative Commons Attribution By license.
Posted by jesseliberty | with no comments
Filed under: ,

Tiny Laptops

 

 

Wind The latest craze among us geeks are the ill-named Nettops; – ill named because they've quickly exceeded the implicit assumption that they are best used for surfing the net and not much else. 

These micro-laptops are now typically under 3 pounds, have keyboards that are around 80-85% the size of a full keyboard and screens in the 8.5 – 11" range. They also cost a pittance.

The first one I saw was the Dell Mini 9. Boy was it sweet. Scott Hanselman fell in love with his, and wrote this great review

He's very convincing. In fact, I bought my MSI WIND about 18 seconds after reading his post. 

--- A digression --

I've mentioned before that at Citibank[1] I worked for a guy named Larry Weiss, who used to describe consumers of electronics as falling into quintiles [5 reactions of technology, though not groups of equal size].  He'd often draw a pyramid like this:

Pyramid

The first quintile is, well,  most of you, and certainly me. Is it new? Interesting? Geeky? I'll buy it. Hock my kid if I have to.  We're buying Nettops now. And adding extra RAM.

2nd quintile will buy it if there is a clear benefit and some experience that shows it works.  Actually, 2nd quintile may be buying now too, things are speeding up since Larry formulated this in the 80's.

Third quintile buys when the technology meets a "felt-need" – they are the bulk of your target audience when you are making mass-market technology (at the time we were talking ATMs and home banking). 

Fourth quintile needs to see a huge benefit, lots of experience, and feel very warm and fuzzy. Those folks are thinking about high speed internet about now.

Fifth quintile: forget it. Pull the trigger, kill me, I'm not using it.

</digression>

Admitting that I'm in the first Quintile and thus bought this before I knew it made perfect sense, I will say that I had some justification: even my small laptop doesn't really fit on the try on jets these days (seats are getting smaller and I'm getting bigger), batteries on most laptops give up too fast to get much work done, and I just signed up to do two books: the reincarnation of the Silverlight book that wasn't (more on that soon) and a book I've wanted to write for a very long time.

The Yowza! effect

But here's what I've discovered, this is another in a line of what I call "Yowza!" devices.  A Yowza! device (and the exclamation mark is part of the term, though if you're in the first quintile, you know that mark by the name "bang") is a device that you buy thinking "I'm a first quintile compulsive person who can't help but buy this and I sure hope it does something useful" and then, somewhat to your surprise, you discover that it is not only useful, but it is essential. Within an amazingly short time,  not only can't you live without it, but you feel a  sacred and moral obligation to tell everyone you know about it.

Here are some Yowza! devices:

  • The VCR
  • Cordless Telephones
  • The Cell Phone
  • The DVR
  • The GPS

Commodity Pricing

While I know that Scott gets great usage out of his Dell 9, the progress in the past few months has been staggering. Here are the basic specs on the computer I bought. But before you read the specs, keep in mind that I spent,  delivered the next day to my door, $400.92.

AmazonInvoice

  • Intel Atom 1.6 GHz Processor
  • 512 KB L2 Cache
  • 1GB RAM + (for $12) a second GB [2]
  • 160 GB 5400 SATA Drive, Windows XP installed
  • 6 Cell Battery
  • 1.3 MP Web Cam
  • Wireless card with 11 b/g/n
  • 10/100 Ethernet
  • Bluetooth
  • Mic, Speakers, Soundblaster
  • 4 in 1 card-reader
  • Weight with battery: 2.8 lbs
  •  

    This is a serious laptop. And, there are lots of others as good (and some would say better). And more are coming every day. 

    (I'm told that Windows 7, Silverlight and the rest of Microsoft's software runs like a top on these machines, and that is good news indeed).

    If I Were Apple, I'd Be Very Worried

      My daughter is incredibly lucky that we bought her Macbook when we did, because I'd be hard pressed to justify spending over three times as much. Her computer is aMacBook2 lot better, but I'm not convinced it's $1,000 better.

    Much more important, and more dangerous for Apple, a lot of parents and a lot of school districts will be asking themselves the same question. Especially if they're buying them by the classroom. Especially when you consider that there is very little software you can't run on XP SP3 with 2 gig of RAM and 160 MB of drive.

    Generally speaking, I'll be putting product reviews on my Reviews page, but this was too relevant to our world to hide in the back. 

    I'm reasonably convinced that these tiny computers are not just a passing phase or an interesting side show, but the harbinger of a trend that will be fed by the confluence of diminished economics and increased bandwidth.

    More soon.

     

    ---------------------

    1 This was back when Citibank was the biggest bank in the world, and solvent, and innovative. After I left, things seemed to….

    2 In the late 1980s I worked for PBS and the cost of RAM was $1,000 / megabyte. Thus, 1 gigabyte would have been $1,280,000.00. It is now $12. That is a savings of 5 orders of magnitude in about 20 years. Amazing.


    This work is licensed under a Creative Commons Attribution By license.

    Moo cards



    You'll have noticed that some of our biz cards seem to have shrunk. This is the "moo card" phenomenon….

    MooDrop Moo is a very hip, very friendly site that will print almost anything for you, but what has clearly caught on is their "mini-cards" which cost only $20USD/100, are full color on one side (with up to six lines of print on the other); come in a very nice box and let you choose what goes on the front from any number of photo sources (your computer, Flikr, Etsy, bebo, Facebook, etc. ) You can have 100 different mages, 100 of the same image, 50 of two images, or whatever combination you want.


    Customer service is top notch and with a little work, even a total non-designer (like me) can make a decent card.

    [Update 1pm GMT-5 Good grief, there was a typo. Here is the fixed card]

     

    moo4a

     moo4b  

     

    Interestingly, ad hoc surveys find people hold on to these more than full size cards, though no one can quite prove that.  In any case, they make great bookmarks.

     

    Mix09Smallest Got these just in time for Mix. You are going, yes?  See you there.

     

    jessesigbg


    This work is licensed under a Creative Commons Attribution By license.
    Posted by jesseliberty | 1 comment(s)
    Filed under: ,

    Using statistics well

    I recently wrote a rant about the use (and overuse) of statistics, and pointed to the Twitter Influence Calculator (now Twitalyzer) as a working example of statistics of questionable value.

    I should have paused.

    It turns out that (a) they are quite thoughtful about the metrics they are using and (b) more important those metrics can in fact teach someone (me for example) how to use Twitter more effectively.

    Twitter is a funny thing, and suggesting it can be used effectively may strike some as risible; but the truth is that in my job, making frequent high:signal contact with the community is valuable, and, it turns out, Twitalyzer zeros in on some of the more interesting aspects of that contact.

    There is the obvious, such as  Influence which they define (in more detail than I will here) as "number of followers, number of times you are retweeted, your generosity (see below), times you are referenced by others and number of updates you publish in a week.  One can argue for different metrics, but it would be hard to make the case that these are absurd.

    Mr. Rogers  In addition to giving you your "score," they go on to tell you your change, which is helpful, and then if you like, how you might improve that score (e.g., you need more followers and friends…. Won't you be my neighbor?)Signal

    The second number they provide is Signal, and they use it exactly in the same way I do when I write "More Signal/ Less Noise" – that is do your tweets contain useful information. They define useful information in this case as any of the following: references to other people, links to urls, hashtags and retweets (given that they must do this by machine and semantics are hard to interpret, this seems reasonable). They even break these out for you in TwitPie a handy pie chart and another chart showing change over time.

    The third value is Generosity, defines as the number of retweets you provide. I was skeptical about the importance of retweeting (in fact, I worried it was just noise) but asked about it on Twitter and received many amazing, thoughtful (brief) responses. Best of the lot was from Bob Martin (@uncleBob) whom I've admired for many years, who wrote "twitter is a loose network of tight clusters. RT is the means for communicating beyond your cluster"  Not only do I find that compelling, it is almost a haiku.

    The penultimate measure on Twitalyzer is Velocity, defined as  the rate at which you tweet. Velocity + signal/noise gives you a good sense of your contribution.

    Finally, Twitalyzer measures your Clout: that is, the number of references to you divided by the total number of possible references (that latter number is a bit fuzzy to me, but I think there is an upper limit set by the Twitter API). In any case, the more folks reference you the more clout you have.

    Charts, Tables and Analysis, Oh My

    Once you've absorbed all that there are endless charts and analysis, but many are targeted at helping you increase your effectiveness, which makes this exercise worthwhile  For example, one analysis offered to me was to compare my average values for number of follwers, retweeting,e tc. with the "11,343 people we're tracking who have about 25% more influence (on average) than you…")  Nice.  What stands out in the chart, right away, is that on average, those folks have more friends than I do (story of my life). Where is Mr. Rogers when I need him?

    All in all, more information than you can shake a virtual stick at, and much of it useful. And a wonderful distraction when you should be working.

    It will be interesting to see (a) how the metrics are refined over time and (b) to what degree the very act of measuring influences that which is measured (The "Liberty's Group Behavior Uncertainty Principle – measuring the activity of a group causes the members of the group to change their activity" (I'm certain I'm not the first to say it.)

    A police officer pulls Werner Heisenberg over for speeding. "Do you know how fast you were going, Herr Doktor?" asks the trooper.  "No," replies the physicist, "but I know exactly where I was."

    Related Resources

    Some Twitter Social Network Analysis
    My Experiences with Twitter Part 1
    Scott Hanselman on How To Use Twitter
    Perl Script for Twitter Analysis

    Previous We Love to Measure Everything


    This work is licensed under a Creative Commons Attribution By license.

    Dispatcher, Cross-Thread Property Setting & Lambda Expressions

    I am finishing up my tutorial on Hyper-video and in the more advanced section I discuss the idea of displaying a button when the video's marker is hit, and then removing the button after a short time has passed.

    To make this work, I instantiate an object of type Timer and pass in the name of the (static) callback method, the button that was pressed, the length of time I want the button to be visible (in milliseconds) and the time between invocations – in this case the value Timout.Infinite to indicate that I do not want the timer to restart after it calls the callback.

     

    Timer t = new Timer(
       EndShowMore,       // call back
       ShowMore,          // state
       2000,              // dueTime
       System.Threading.Timeout.Infinite   // period
       );

     

    When the timer dueTime (2 seconds) passes  the callback method (EndShowMore)is invoked.

    As noted, EndShowMore must be static. Its job is to make the button invisible and disabled. But the static method and the button are in different threads and so the method cannot set these properties directly.

    What is needed is a dispatcher in the same thread as the controls. Fortunately, the button (ShowMore) is provided as an argument to the callback (you passed it in as the second parameter to the Timer constructor.)

    Once we cast that state object back to type Button we can grab its Dispatcher and use that to call BeginInvoke which will execute a method asynchronously through a delegate.

    iStock_connectTwoWiresXSmall

    You can write the EndShowMore call back as follows,

    private static void EndShowMore( object state )
    {
      Button btn = (Button) state;
      btn.Dispatcher.BeginInvoke(
         delegate() { btn.IsEnabled = false; } );
      btn.Dispatcher.BeginInvoke(
         delegate() { btn.Visibility = Visibility.Collapsed; } );
    }

    That will certainly work but the syntax is a bit cumbersome. I find the use of a Lambda expression makes the intent clearer and the code a bit simpler,

    private static void EndShowMore( object state )
    {
       Button btn = (Button) state;
       btn.Dispatcher.BeginInvoke( () => btn.IsEnabled = false );
       btn.Dispatcher.BeginInvoke( 
    () => btn.Visibility = Visibility.Collapsed ); }
    
    

    More On Hyper-Video

    For more on the subject of Hypervideo see the thread of blog posts that starts here or these How Do I videos: Part 1, Part 2Part 3. The tutorials (in C# and VB) on Hypervideo should be posted before Mix.


    This work is licensed under a Creative Commons Attribution By license.