Friday, February 26, 2010

Column guides for Visual Studio 2010: An extension

Column guides for Visual Studio 2010: An extension


Column guides for Visual Studio 2010: An extension

Posted: 26 Feb 2010 12:44 PM PST

On the Silverlight team, I use this Visual Studio 2010 extension to keep my comments looking pretty....( read more )...(read more)

View/ViewModel Association - Convention and Configuration-based Approaches

Posted: 26 Feb 2010 10:47 AM PST

Some time back, I blogged about different options to hook up a view to its view model when following the ViewModel (aka MVVM) pattern. There are multiple approaches in use out there. I raised the possibility of a convention-based approach in addition...( read more )...(read more)

View/ViewModel Association - Convention and Configuration-based Approaches

Posted: 26 Feb 2010 10:47 AM PST

Some time back, I blogged about different options to hook up a view to its view model when following the ViewModel (aka MVVM) pattern. There are multiple approaches in use out there. I raised the possibility of a convention-based approach in addition Read More......(read more)

When Is It OK To Hack?

Posted: 26 Feb 2010 09:14 AM PST

This mini-tutorial is part of the SLHVP documentation   One of the goals of the Silverlight HyperVideo Project is to demonstrate best practices.  So when is it okay to throw in a quick hack to get things working? Case in point: as I approached...( read more )...(read more)

View/ViewModel Association - Convention and Configuration-based Approaches

Posted: 26 Feb 2010 10:47 AM PST

Some time back, I blogged about different options to hook up a view to its view model when following the ViewModel (aka MVVM) pattern. There are multiple approaches in use out there. I raised the possibility of a convention-based approach in addition to existing ones like the ViewModelLocator pattern. Motivation: I find the simplest way to explain ViewModel is to present it as a better code-behind , especially to the mainstream developer who is intimately familiar with the latter (at least in the .net world). With the code-behind approach the UI, its state and operations are all mixed up. The ViewModel pattern is of course designed to help separate application logic from the view, but now results in two discrete halves that need to be reconnected...(read more)

When Is It OK To Hack?

Posted: 26 Feb 2010 09:14 AM PST

MiniTutorialLogo

This mini-tutorial is part of the SLHVP documentation

 

One of the goals of the Silverlight HyperVideo Project is to demonstrate best practices.  So when is it okay to throw in a quick hack to get things working?

CutDownPlayerCase in point: as I approached the release this week for the latest alpha,  I noted that the player was not updating when the user clicked on a topic, though the links were appearing as if  the player had been advanced.

To make the issue clear, in this image you see a cut down version of the player. Each item (video) has its own set of topics and links. The topics are shown as soon as the video starts, the links appear as the video plays.

If the user clicks on a topic (lower left) what should happen is that the video (middle) jumps to that topic and the scrubber  (below the video) should advance to indicate where in the video the topic begins, relative to the start of the video.

(Click on image to see it full size)

After a bit of debugging (and some frantic calls to the Vertigo folks who wrote the Silverlight Media Framework, we were able to see that the problem was in the binding:

<SmoothPlayer:Player Style="{StaticResource SLHVPTemplate}"  x:Name="smoothPlayer">     <hvp:HVPCoreMediaElement x:Name="corePlayer"       SmoothStreamingSource="{Binding URI, Mode=TwoWay}"      AutoPlay="True"     Position="{Binding Offset, Mode=TwoWay}" /> </SmoothPlayer:Player>

Checking the source code for the SMF (available here) we found that Position is a dependency property and was not responding to the Binding as we expected.

Since the folks at Vertigo owned that code and were convinced they could fix this in the next release, I opted to take their change an copy it into my project. To encapsulate the hack, however, I created the HVPCoreMediaElement, derived from the CoreSmoothStreamingMediaElement. 

 

using System; using System.Windows; using Microsoft.SilverlightMediaFramework.Player;  namespace SilverlightHVP.View {    public class HVPCoreMediaElement :             CoreSmoothStreamingMediaElement    {       public TimeSpan PositionOverride       {          get { return ( TimeSpan ) GetValue( PositionOverrideProperty ); }          set { SetValue( PositionOverrideProperty, value ); }       }        public static readonly DependencyProperty PositionOverrideProperty =              DependencyProperty.Register(                  "PositionOverride",                  typeof( TimeSpan ),                  typeof( CoreSmoothStreamingMediaElement ),              new PropertyMetadata( HVPCoreMediaElement.OnPositionOverridePropertyChanged ) );        private static void OnPositionOverridePropertyChanged(              DependencyObject d, DependencyPropertyChangedEventArgs e )       {          HVPCoreMediaElement source = d as HVPCoreMediaElement;          source.OnPositionOverrideChanged();       }        private void OnPositionOverrideChanged()       {          // Hack!!, to databind to Position          Position = PositionOverride;       }    } }

I could then modify the binding

<SmoothPlayer:Player Style="{StaticResource SLHVPTemplate}"  x:Name="smoothPlayer"     >     <hvp:HVPCoreMediaElement x:Name="corePlayer"       SmoothStreamingSource="{Binding URI, Mode=TwoWay}" AutoPlay="True"     PositionOverride="{Binding Offset, Mode=TwoWay}"   </SmoothPlayer:Player>

And all was right with the world.   This was minimally intrusive, and I was very pleased with it.  I should have known.

In For A Penny…

The problem, of course, is that now that I'm binding the new PositionOverride I'm reading wonderfully, but writing, not so.  There are a lot of ways to fix this, but the easiest, fastest and perhaps ugliest is to add a second binding. After all, binding to Position was working great for setting, and PositionOverride is now working great for reading. 

<SmoothPlayer:Player Style="{StaticResource SLHVPTemplate}"  x:Name="smoothPlayer"     >     <hvp:HVPCoreMediaElement x:Name="corePlayer"       SmoothStreamingSource="{Binding URI, Mode=TwoWay}" AutoPlay="True"     PositionOverride="{Binding Offset}"       Position="{Binding PlayerPosition, Mode=TwoWay}" /> </SmoothPlayer:Player>

If this were the only change, maybe okay, but unfortunately we have to hack the VM as well,

public TimeSpan Offset {  get { return state.Position; } }  public TimeSpan PlayerPosition {    get { return state.Position; }     set    {       if ( value > previousPosition + Interval )       {          previousPosition = value;          state.Position = value;       }    } }

Oh What A Tangled Web We Weave…

This is so ugly, and so likely to end up being a headache when we are ready to undo it, that I'm very tempted to find a cleaner solution. On the other hand, I know that we're actively working on SMF version 2, and that even before that I may have an interim release that makes the whole problem go away, so my Faustian bargain is to comment the hack

/*   HACK!! We are binding the getter of Offset to the Position of the CoreSmoothStreamingMediaElement      but we are binding the setter to the PositionOverride property of the (temporary) class HVPCoreMediaElement that      derives from CoreSmoothStreamingMediaElement.  Also note that this is two way binding and we need both the getter      and the setter.       To Fix:          1. Combine move get and set from PlayerPosition to Offset and remove PlayerPosition         2. Change Binding in SmoothStreamingPlayer to bind to Offset, two way         3. Remove file (and class) HVPCoreMediaElement.cs */   public TimeSpan Offset {  get { return state.Position; } }   public TimeSpan PlayerPosition  {     get { return state.Position; }      set     {        if ( value > previousPosition + Interval )        {           previousPosition = value;           state.Position = value;        }     }  }

Let the Flame Wars Begin

"Well?," as Howie Mandel's tiny alter-ego Bobby asks, "what would you say?"

This work is licensed under a Creative Commons license.

Circular Accordion Style Silverlight 3

Posted: 26 Feb 2010 06:39 AM PST

This morning I created a Circular Accordion Style for the Silverlight 3 Toolkit Accordion Control. Everything is circular. As always: Pure XAML built with Expression Blend 3. View the example and download the sourcecode at the Expression Gallery . Best...( read more )...(read more)

Highlighting a "weak" contribution [Enhancements make preventing memory leaks with WeakEventListener even easier!]

Posted: 25 Feb 2010 10:13 AM PST

It was back in March of last year that I explained the motivation for the WeakEventListener class I'd started using in the Silverlight Toolkit 's Data Visualization assembly. Since then, a few other Toolkit controls have added WeakEventListener where...( read more )...(read more)

No comments:

Post a Comment