If you use the Slider object in Silverlight (or WPF for that matter) you may have experienced some similar frustration that I have recently.  Let’s take a look at what the Slider is first.

The Slider is a simple control on the surface providing a track and a “thumb” (if you aren’t familiar with that term) that enables value changing.  Some of the key properties are:

    • Minimum – the number that represents the lowest (left or bottom) value
    • Maximum – the number that represents the highest (right or top) value
    • LargeChange – the slip when a large change in value is desired
    • SmallChange – the slip when a small change in value is desired

It is the last two properties that caused me some headache.  To understand, let me try to explain the functionality first.  Looking at the image above, you’ll see that the track is a certain length.  In my setting I have Minimum set to 1 and Maximum set to 100 above.  Therefore the current Thumb position (Value) is about 20.  Notice where the mouse cursor is?  If I were to actually click there here is what the result would be:

What?!  You may be asking yourself the same thing.  Why didn’t the Thumb move to the curser clicked position?  How did it determine where to move?  Enter the Small/Large change values.  In my setting I have LargeChange set to 10.  What is happening is when I visually click on position at about 80, the Slider sees a large change occurring and moves one LargeChange value.  If I would have clicked close to the Thumb, SmallChange would have happened as well.  This is quite annoying when your users will probably expect that clicking on the track will take them to that point.

Incidentally, the WPF Slider has a property called IsMoveToPointEnabled which turns this functionality on.  This property is not available in the Silverlight Slider (as of Beta 2).

So what if you need that functionality?  Well, here’s one way (with a hat not to my colleague John Lemire for turning me on to this method).  This does involve some code and modifying the template, but it isn’t that painful at all.

Modify the Template

Using Expression Blend, we can modify what the template definition of a Slider is.  To do this, open up the project in Blend, select the Slider object, right-click and choose Edit Control Parts (Template)…Edit a Copy.  Give it a name (I named mine CustomSlider and kept it as a document resource as opposed to an Appliction one).  You’ll then see that you can now edit the template.  There is actually a template for Horizontal and Vertical (Slider has an orientation property), but let’s just concentrate on Horizontal.  The template is made up of: Rectangle, 2 RepeatButtons and a Thumb.  Make sure the Thumb is named “HorizontalThumb” as we’ll need to refer to it later.  Now let’s add some Rectangles.

We’re going to add Rectangles “on top” of the RepeatButtons in use.  You see, when you click on the track in Slider, you’re actually clicking on the RepeatButton areas.  So right now our default template should look like this (for the HorizontalTemplate area only):

   1: <Grid x:Name="HorizontalTemplate">
   2:     <Grid.ColumnDefinitions>
   3:         <ColumnDefinition Width="Auto"/>
   4:         <ColumnDefinition Width="Auto"/>
   5:         <ColumnDefinition Width="*"/>
   6:     </Grid.ColumnDefinitions>
   7:     <Rectangle Height="3" Margin="5,0,5,0" Grid.Column="0" Grid.ColumnSpan="3" Fill="#FFE6EFF7" Stroke="Black" StrokeThickness="0.5"/>
   8:     <RepeatButton IsTabStop="False" Template="{StaticResource RepeatButtonTemplate}" x:Name="HorizontalTrackLargeChangeDecreaseRepeatButton" Grid.Column="0"/>
   9:     <Thumb Height="18" x:Name="HorizontalThumb" Width="11" Grid.Column="1"/>
  10:     <RepeatButton IsTabStop="False" Template="{StaticResource RepeatButtonTemplate}" x:Name="HorizontalTrackLargeChangeIncreaseRepeatButton" Grid.Column="2"/>
  11: </Grid>

We’re now going to add 2 Rectangles, one after the left RepeatButton and one after the right RepeatButton, named LeftTrack and RightTrack respectively.  You can do this in the XAML code or just drag the Rectangles on the design surface in Blend and arrange accordingly.  The result should be this:

   1: <Grid x:Name="HorizontalTemplate">
   2:     <Grid.ColumnDefinitions>
   3:         <ColumnDefinition Width="Auto"/>
   4:         <ColumnDefinition Width="Auto"/>
   5:         <ColumnDefinition Width="*"/>
   6:     </Grid.ColumnDefinitions>
   7:     <Rectangle Height="3" Margin="5,0,5,0" Grid.Column="0" Grid.ColumnSpan="3" Fill="#FFE6EFF7" Stroke="Black" StrokeThickness="0.5"/>
   8:     <RepeatButton IsTabStop="False" Template="{StaticResource RepeatButtonTemplate}" x:Name="HorizontalTrackLargeChangeDecreaseRepeatButton" Grid.Column="0"/>
   9:     <Rectangle x:Name="LeftTrack" Grid.Row="1" Fill="#00FFFFFF" Cursor="Hand"/>
  10:     <Thumb Height="18" x:Name="HorizontalThumb" Width="11" Grid.Column="1"/>
  11:     <RepeatButton IsTabStop="False" Template="{StaticResource RepeatButtonTemplate}" x:Name="HorizontalTrackLargeChangeIncreaseRepeatButton" Grid.Column="2"/>
  12:     <Rectangle x:Name="RightTrack" Grid.Column="2" Grid.Row="1" Fill="#00FFFFFF" Cursor="Hand"/>
  13: </Grid>

Visually you won’t be able to notice any difference because we added Rectangle elements that are have 0% opacity, so the Slider still looks the same.

Create Custom Slider Code

Ok, now let’s move on to code.  I use Visual Studio 2008, so I’ll be referring to that.  In Blend, you can right-click on the project and choose to Edit in Visual Studio which will open the project in Visual Studio for you.  Once open in Visual Studio, add a new Class to your project, I called mine CustomSliderControl.  We’re going to inherit from Slider so we can implement all the same features, we are just augmenting one of them.

We will need a reference to the Thumb and the two Left/Right Track elements we just added, so we’re going to make those member variables we can refer to later.  We’re going to override one function: OnApplyTemplate.  The overriding of OnApplyTemplate is only to set our member variables to the elements we’ll use in the other functions as well as set event handlers on our Left/Right Track Rectangles we added to the template.  Since our elements exist in a ControlTemplate, rather than use something like FindName, we’re going to use GetTemplateChild and refer to the name (the x:Name) of the element.

We’re also implementing our own function OnMoveThumbToMouse, which will be attached to the MouseLeftButtonDown events on Left/Right Track.  This function basically gets the Point position of the event (the mouse click) and sets the Value of our Sider to that position (based on looking at where it is in relation to the other elements).  When it is all said and done, our CustomSliderControl code in complete should look like this:

   1: using System;
   2: using System.Net;
   3: using System.Windows;
   4: using System.Windows.Controls;
   5: using System.Windows.Documents;
   6: using System.Windows.Ink;
   7: using System.Windows.Input;
   8: using System.Windows.Media;
   9: using System.Windows.Media.Animation;
  10: using System.Windows.Shapes;
  11: using System.Windows.Controls.Primitives;
  12:  
  13: namespace CustomSlider_CS
  14: {
  15:     public class CustomSliderControl : Slider
  16:     {
  17:         private Thumb _HorizontalThumb;
  18:         private FrameworkElement left;
  19:         private FrameworkElement right;
  20:  
  21:         public CustomSliderControl() { }
  22:  
  23:         public override void OnApplyTemplate()
  24:         {
  25:             base.OnApplyTemplate();
  26:  
  27:             _HorizontalThumb = GetTemplateChild("HorizontalThumb") as Thumb;
  28:  
  29:             left = GetTemplateChild("LeftTrack") as FrameworkElement;
  30:             right = GetTemplateChild("RightTrack") as FrameworkElement;
  31:  
  32:             if (left != null) left.MouseLeftButtonDown += new MouseButtonEventHandler(OnMoveThumbToMouse);
  33:             if (right != null) right.MouseLeftButtonDown += new MouseButtonEventHandler(OnMoveThumbToMouse);
  34:         }
  35:  
  36:         private void OnMoveThumbToMouse(object sender, MouseButtonEventArgs e)
  37:         {
  38:             Point p = e.GetPosition(this);
  39:  
  40:             Value = (p.X - (_HorizontalThumb.ActualWidth / 2)) / (ActualWidth - _HorizontalThumb.ActualWidth) * Maximum;
  41:         }
  42:     }
  43: }

Using the Custom Control

Now that we have this custom Slider, let’s use it.  If we go back to our Page.xaml (or whatever XAML where you had the Slider control to begin with) we need to add a few things.  First at the top, we need to add our XAML namespace so we can use it.  For my sample code I used this (my UserControl decorations):

   1: <UserControl
   2:     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   3:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   4:     x:Class="CustomSlider_CS.Page"
   5:     xmlns:my="clr-namespace:CustomSlider_CS"
   6:     Width="Auto" Height="Auto" 
   7:     xmlns:vsm="clr-namespace:System.Windows;assembly=System.Windows">

Notice the “xmlns:my” decoration that points to my CLR namespace for my project.  This will enable me to use this in my XAML later.  Now I can simply find where I used <Slider/> and change to <my:CustomSliderControl/> like this:

   1: <my:CustomSliderControl Cursor="Hand" HorizontalAlignment="Stretch" 
   2:                                 Margin="8,17,8,20.0499992370605" VerticalAlignment="Stretch" 
   3:                                 LargeChange="10" Maximum="100" SmallChange="1" Value="20" 
   4:                                 x:Name="MySlider" Style="{StaticResource CustomSlider}"/>

I don’t have to change anything else, nor do I have to change the Style attribute.  Since our custom control inherits from Slider, all the other types still apply.  You’ll notice that the style itself still has the TargetType=”Slider” attribution and this will work for our custom type because it is a derivative.  Here’s the result (using Silverlight Streaming): click here.

Summary

So as you can see we can extend some of the base controls rather easily.  I hope this didn’t sound too confusing because it really isn’t.  You can download the entire source here in C# or VB to see for yourself.  This particular extension may be helpful when using Slider as a media track representing the timeline for a particular media element.

I hope this helps!

I’m pretty excited about the upcoming Fall travels I have.  Fresh on the heels of a 3-day session with the entire Silverlight team this past week, I’m rejuvenated and ready to rock.  I’ve also got some travels coming up and hope to see some of you at them as well…

Troubleshooting Data Services in Silverlight (09 SEP)

Tomorrow I’ll be presenting a webcast with the goal of trying to help surface some of the more common ‘gotchas’ in dealing with accessing data in Silverlight.  Some of it may not be new to some, but there has been enough posts/emails/etc. where I think sometimes seeing the issues/tools helps to better understand how to avoid them, or at worst, figure out how to stop banging your head against the wall.

PDC08 (27 OCT)

The premier Microsoft developer conference is upon us.  Thousands of us super geeky dev types will be converging upon Los Angeles to see what the next generation of developer technologies has to offer.  I know there will be a lot of great sessions all around, but of course I’m particularly excited about some of the things that the Silverlight team will be presenting.  They just posted 50 new sessions!

.NET Virtual Conference (28 OCT)

How can I be in 2 places at once?  Virtualization baby!  I’ll be joining a few folks for a virtual conference.  It looks like a great lineup of speakers and content.  If you will not be at PDC, check out this option…it’s only $100!  I’ll be speaking three sessions on Silverlight 2 development of course.

Øredev (19 NOV)

I’ll be headed to Malmö, Sweden in November to join a bunch of others at one of the premier developer conferences in that area.  I’m going to be presenting on Silverlight in a few sessions along with others from the Silverlight team.  If you are in the area, please be sure to come to the conference and visit us!

Something great in each month and I’m excited for each of them.  I’ll be spending a little holiday time with my family next week and will be dark, but will be back refreshed and ready to get going on some ideas I’ve been having in my head for way too long.

I hope to see you at one of these above!

There has been much a news about the use of Flash for Sunday NFL games on the NBC web site.  Some have claimed that NBC “dumped” Silverlight.  Whatever.  Anyone who thinks only one person at a company the size of NBC makes the decision does not understand corporate America in large companies.  NBC is a giant company of companies, probably each operating in their own right and left hands never talking to right hands.  That’s not to diminish the work for the NFL site, just a reality of business.

What is ironic about this implementation is that it proves that no technology is immune to business deals.  What do I mean?  Well, when the NBCOlympics.com site was introduced there were some critics of the actual implementation (not the quality, but the features).  People were upset about no full-screen as well as the inability to see the content outside the US from the NBC site.

Enter NFL on NBC.  Think Flash is immune and could “solve” that?  Think again.  Like most implementations of web applications, the NFL site developed for the lowest common denominator to meet their customers.  First, they target a 1024 screen resolution.  Second, no full-screen capability.  Third, users outside the US cannot view the content.

It is the latter two that I mean with regard to no technology immunity.  Why no full-screen?  Um, you think the advertisers want their ad space to disappear?  I bet not.  I’m pretty sure Spring paid good money to be visible the entire time.  One may be quick to point out overlays and such.  Quite frankly, I agree.  I’m not sure why developers don’t offer up the ability to do overlays on the media much like the experience that we see on regular television.  My guess here is that existing ad platforms are serving up content and the paradigm hasn’t shifted to in-media insertion just yet.  I know that Silverlight Streaming services is experimenting with contextual media advertising and I’m sure others are.  Until then, you won’t be seeing many full-screen applications unless the advertisers are in that full-screen experience…get used to it until this changes.  I bet NFL would have loved to have a full-screen experience.

On to the second one, non-US viewers.  They’ll be greeted with this:

NFL non-US image

Ironically, when the Olympics came out I saw many more “Microsoft you suck” for this more than “NBC you suck.”  So where is the “Adobe you suck” comments?  Anywhoo…you can “blame” nobody but NBC.  Welcome to the world of digital rights.  The broadcast rights for the NFL are probably sold regionally and NBC owns the rights to the US (I’m sure there are other countries licensing the rights to NFL online as well).  So for this particular experience provided by NBC US, they are honoring that license.  “Blame” is such a strong word.  I’m sure NBC and their advertisers would love to have as many eyeballs on the site as possible…but they are honoring their legal agreements.

So it just goes to show that no technology is immune to decisions made by business and as well in the world of media, decisions around content licensing.  Maybe we’ll come to a world of “open source content” but it isn’t there yet and implementers of technology will have to abide by these guidelines.

So my thoughts about the player?  Well, my first introduction was a note on Twitter and I went to check it out.  I was immediately placed into a “virtual waiting room” (with no virtual free drinks or appetizers mind you) with a message that said something to the effect of ‘due to overwhelming demand…’ and stayed at that state for a bit.  I eventually was placed in, but found it strange that they wouldn’t plan for “overwhelming demand.”  I’ve come now to realize that is the default message…hmm, I might consider changing that.

Once I did get in the quality of the game I was watching wasn’t great at all.  This was echoed by some on the Internet as well.  I experienced a very pixelated view that was choppy/buffering.  I didn’t get a chance to tune in tonight (07 SEP) to see the game online, but will compare this week.  In contrast, the recent Amazon implementation is much better quality.  I think the critical difference here is live versus pre-encoded where you have more time over the quality of the encode.  Some would say an outfit the size of NFL/NBC should have the highest quality hardware encoders available to them and that is no excuse, but I’m not privy to the equipment they are using.  For me, it wasn’t a great experience at all on the quality front.

Being that I have a soapbox on non-plugin-installed experiences, I checked that as well.  People give Silverlight a lot of crap for the default install badge that lazy developers don’t take the time to change (that’s right, I’m calling you out…fix your install experience).  I realize that Flash is pretty readily available on most machines, but I wanted to check the experience if I didn’t have Flash:

Nice.  Someone might want to take a look.  I assume the “Get Adobe Flash Player” is the default from some of the Flex tools.  For a site like NBC/NFL they should really put some design effort into this.  It tells me nothing about the content.  Say what you want about ubiquity, but it’s lazy.  And yes, if I see a production Microsoft site with the default “install Silverlight” badge, I’d call them out too – they’d be lazy as well.

I hope that over time, old media will meet new media and the online experience will continue to get better.  The Democratic National Convention proved that it is possible to deliver HD quality media live and scalable.  Here’s to hoping more online media gets that way.  I really liked last year watching next-day online episodes on ABC (it enabled me to keep in touch with LOST while traveling) in an HD-experience (that experience was powered by Move networks) and site like Hulu as well give us hope for increasingly better online media.  Now lets get those advertisers inline so we can get features we want as well without being imparied by old media rules/platforms.


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

Two new resources came to my attention recently that could be helpful resources for Flash developers wanting to learn Silverlight.  The first has been out there for a bit actually, but the other is new.  Let’s start with the new one, (video).  As Adam Kinney said this week while in meetings in Redmond, “because we need another web site.”

Project Rosetta describes itself as:

Project Rosetta is a site dedicated to helping designers and developers build applications in Silverlight while taking advantage of skills they already know.

There are two articles up there now, The New Iteration and From Flash to Silverlight.  The newest article involves a Flash maestro, .  The articles aren’t blog posts, but rather more in-depth discussions of various aspects of design/development where your skills can be re-used while doing development for Silverlight.

The second resource is a blog called Shine Draw from Terence Tsang and describes itself as Your Flash and Silverlight Repository.  Terence has 6 years of Flash experience, but even concedes he is not as much of an expert as he aspires to be.  This site is great in that he combines the knowledge of Flash with the concepts of image and animation to see how things are done in each respective technology.  Terence starts with a concept/question to himself (i.e., 3D image navigation) and then goes about creating that sample in both Flash and Silverlight…with the goal of an same experience in each technology.  He provides code for both (Flash 9/AS3 and Silverlight 2/C#) as well as documents the time it took to do each example.  It’s really an intriguing read and some helpful nuggets of code as well.  Oh yeah, and he takes requests.

I hope you find these useful, or at least interesting…I certainly have.

Earlier this year I wrote my thoughts on the current mobile scene and what troubles certain players more than others.  I made the assertion that Android will face the same troubles that Windows Mobile is challenged with.  That being that Google/Android are providing a platform and not a physical device.  I think it would be hard to argue that owning the complete platform and hardware is not a good idea.  Apple’s complete control of every aspect of the channel provides them with the ability to deliver in a somewhat more reliable fashion (except for the fact that Contacts suck and their implementation of ‘enterprise’ features is questionable).

So why another post on the failure of Android?  Take a look:


(source: CrunchGear)

What you can’t really see in the photograph is the proposed angle of the button controls (they angle upward in other design drawings/renderings), making it look like a more old-school handset more than a revolutionary device.

And therein lies the struggle for Android: they aren’t making the device.  I’ve seen the demos of Android and have already said they are impressive.  The fact that all of that is made available via open source is great and exciting.  But for consumers, useless unless some great packaging comes with it.  Remember the old adage of lipstick on a pig?  When I look at the above T-Mobile picture device running Android, that’s what I think about.  There isn’t anything innovative in the design and regardless of innovation it doesn’t even match some of the sleekness of current designs.  In the consumer market, design matters over features. 

I will say that the “HTC Dream” has other shots/drawings around that look a lot different than the above picture, so I could be eating my words.  But right now it looks like a Nintendo Wii accessory.  And in some angles it looks like an iPod sized thing with an FM transmitter adapter on the bottom…just not polished.

I foresee a bunch of Silicon Valley types walking around with this device, but my wife won’t be carrying it because it looks too Star Trek-ish.

Better view of the weird angle bottom in this video ("is that Android in your pocket or are you just happy to see me?"):