Monthly Archives: April 2007

Still related with Silverlight

Lutz has released a new version of Reflector with Silverlight support (if you already downloaded a previous version, just run the update checker if you don”t get prompted for an automatic update). There”s alsoe  monotone demo app for silverlight. Go get it!

SDKs for Silverlight available!

What can I say? I should have complained earlier! :,,)

Silverlight SDKs links broken

damn! there goes all the joy!

Silvelight beta is out!

According to Mike Harsh, there”s a new release with .NET support. It seems like now we”ve got a new site, new forums and new samples. Everything is concentrated on a single page. It”s time to start looking at Silverlight!

Silverlight: simplifying the FilmStrip sample

Today I”ve started looking at the samples that accompany Silverlight. I started with the FilmStrip sample. After looking at it for some minutes, I thought that maybe I could simplify the code needed to achieve the image transitions. If you look at the original code, you”ll see that there are several storyboards that set up each transition. you”ll also see that they”re really duplicates and that the only thing that changes is the value of the Value property applied to the SplineDoubleKeyFrame element. In fact, if you pay attention to the storyboards, you”ll see that each storyboard decreases (or increases, depending on the direction you follow :) ,,) the value by 1024.

So, what”s happening here is that these extra lines of XAML (for each transition) could be reduced to one storyboard whose value is changed during the click of the next/previous button. To achieve this, you should start by removing all the extra storyboards and kepp only one. In my case, I”ve ended up with this xaml (i”m only putting the inner loadedRoot canva”s triggers xaml):

<Canvas.Triggers>
 <EventTrigger RoutedEvent=”Canvas.Loaded”>
  <EventTrigger.Actions>
    <BeginStoryboard>
       <Storyboard BeginTime=”5″ Duration=”00:00:01″ x:Name=”story”>
             <DoubleAnimationUsingKeyFrames BeginTime=”00:00:00″ Storyboard.TargetProperty=”X”  Storyboard.TargetName=”slideX1″>
                <SplineDoubleKeyFrame
                       Name=”anim1″
                       KeySpline=”0.7,0,0.4,1″ Value=”0″ KeyTime=”00:00:00.8″/>
           </DoubleAnimationUsingKeyFrames>
          <DoubleAnimationUsingKeyFrames BeginTime=”00:00:00″ Storyboard.TargetProperty=”X” Storyboard.TargetName=”slideX2″>
                <SplineDoubleKeyFrame
                     Name=”anim2″
                     KeySpline=”0.7,0,0.4,1″ Value=”1024″ KeyTime=”00:00:00.8″/>
           </DoubleAnimationUsingKeyFrames>
          <DoubleAnimationUsingKeyFrames BeginTime=”00:00:00″ Storyboard.TargetProperty=”X” Storyboard.TargetName=”slideX3″>
                <SplineDoubleKeyFrame
                    Name=”anim3″
                    KeySpline=”0.7,0,0.4,1″ Value=”2048″ KeyTime=”00:00:00.8″/>
         </DoubleAnimationUsingKeyFrames>
         <DoubleAnimationUsingKeyFrames BeginTime=”00:00:00″ Storyboard.TargetProperty=”X” Storyboard.TargetName=”slideX4″>
              <SplineDoubleKeyFrame
                  Name=”anim4″ 
                  KeySpline=”0.7,0,0.4,1″ Value=”3072″ KeyTime=”00:00:00.8″/>
         </DoubleAnimationUsingKeyFrames>
         <DoubleAnimationUsingKeyFrames BeginTime=”00:00:00″ Storyboard.TargetProperty=”X” Storyboard.TargetName=”slideX5″>
             <SplineDoubleKeyFrame
                Name=”anim5″
                KeySpline=”0.7,0,0.4,1″ Value=”4096″ KeyTime=”00:00:00.8″/>
       </DoubleAnimationUsingKeyFrames>
       <DoubleAnimationUsingKeyFrames BeginTime=”00:00:00″ Storyboard.TargetProperty=”X” Storyboard.TargetName=”slideX6″>
          <SplineDoubleKeyFrame
              Name=”anim6″
              KeySpline=”0.7,0,0.4,1″ Value=”5120″ KeyTime=”00:00:00.8″/>
       </DoubleAnimationUsingKeyFrames>
      <DoubleAnimationUsingKeyFrames BeginTime=”00:00:00″ Storyboard.TargetProperty=”X” Storyboard.TargetName=”slideX7″>
         <SplineDoubleKeyFrame
             Name=”anim7″ 
              KeySpline=”0.7,0,0.4,1″ Value=”6144″ KeyTime=”00:00:00.8″/>
      </DoubleAnimationUsingKeyFrames>
      <DoubleAnimationUsingKeyFrames BeginTime=”00:00:00″ Storyboard.TargetProperty=”X” Storyboard.TargetName=”slideX8″>
          <SplineDoubleKeyFrame
               Name=”anim8″ 
               KeySpline=”0.7,0,0.4,1″ Value=”7168″ KeyTime=”00:00:00.8″/>
       </DoubleAnimationUsingKeyFrames>
     </Storyboard>
    </BeginStoryboard>
  </EventTrigger.Actions>
 </EventTrigger>
</Canvas.Triggers>

As you can see, I”ve changed the name of the storyboard to story and I”ve named each of the SplineDoubleKeyFrame so that we can change its Value during each button click. As I”ve said, in the initial sample each storyboard would be an exact copy of the previous: the only thing that changes is the value of Value property (and this value is decremented by 1024 in each element). With this knowledge, we just need to build a function that increments or decrements each of the animation by the necessary factor:

function updateAnims( factor ){
   for( var i = 1; i < 9; i++ ){
        wpfe.findName( “anim” + i ).Value = wpfe.findName( “anim” + i ).Value – factor;
   }
}

Changing the upForward method to use the new strategy is really simple:

function upForward (s,e) {
  if (currentSlide < 8) {
     currentSlide++;
     var factor = 1024;
     updateAnims( factor );
     wpfe.findName(“story”).Begin();
     if (currentSlide < 8) {
        wpfe.findNa me(“forwardButton”).fill = “#FF000000″
        wpfe.findName(“forwardButton”).stroke = “#FFAAAAAA”
    }
    else {
        wpfe.findName(“forwardButton”).fill = “#FF000000″
        wpfe.findName(“forwardButton”).stroke = “#FF222222″
    }
  }
  wpfe.findName(“backButton”).fill = “#FF000000″
  wpfe.findName(“backButton”).stroke = “#FFAAAAAA”
}

All that is needed is to update the animations before running them (this is only possible because the animation retains its final value after beeing run). You”ll also need to change the upBack method so that it updates the animation values with negative values:

//….previous code removed
currentSlide–;
var factor = 1024;
updateAnims( -factor );

wpfe.findName(“story”).begin();

While performing these changes, I”ve also noticed that each image is downloaded through its own Downloader object, which also seemed a waste of resources. After looking at the docs, it seemed like I couldn”t use only one downloader for all the images because loading ad image could only be done by setting a path or associating a Downloader with it. I though that if I associated a downloader with an Image and then downloaded a second image with the same downloader, that isecond mage would be rendered in the associated Image control (ie, i thought that callluing the SetSource method would result in creating a binding between the Image and the Downloader). Since I didn”t find any way to explicitly set the bytes of the image, I thought that those extra-Downloader objects were really necessary. Even though it seemed like I was wasting time, I”ve changed the code so that it only used one downloader. The first thing I did was create a global method with the following code:

function __getDownloader(){
  if( downloader == null ){
      downloader = wpfe.createObject(“Downloader”);
      downloader.downloadProgressChanged = “javascript:downloadProgressChanged”
      downloader.completed = “javascript:downloadCompleted”
  }
  return downloader;
}

And the, I”ve replaced these lines (in the downloadAssets and downloadCompleted methods):

downloader = wpfe.createObject(“Downloader”);
downloader.downloadProgressChanged = “javascript:downloadProgressChanged”
downloader.completed = “javascript:downloadCompleted”;

with this one:

downloader = __getDownloader();

After opening the page in the browser, I though that I”d get the last picture eight times. But that didn”t happen…it worked, ie, using a single Downloader was more than enough to get all the images…So, it seemed like this sample was a little “bloated” after all…

Anti-spam software for Exchange Server Free Disclaimer

Anti-spam software for Exchange Server

WSUS Product Team Blog : Update on svchost/msi performance issue and 3.0 Client distribution plan

Update on svchost/msi performance issue and 3.0 Client distribution plan

Strangest Vista bug?

Michael Howard describes what a strange vista bug :,,)

Building controls for Silverlight

I decided spending 1 or 2 hours looking at how we could build and encapsulate controls with Silverlight and Javascript (nothing too fancy). It was a great exercise since it helped  me understand a little more about the limitations of the current version of Silverlight. Unfortunately, 1 or 2 hours weren”t enough to build a really cool framework. However, it was more than sufficient to get a small proof of concept showing that it is possible to build a framework where you have Javascript classes that are capable of injecting xaml and intercepting the events generated by those elements. When I started thinking about this, I had the following objectives:

  • the controls should be able to inject XAML into a Canvas (or another) object specified as its parent element;
  • the controls should encapsulate all the logic for making its transition beween states (this means that it should handle mouse enter/leave events, etc);
  • the controls should fire events that can be handled by the page programmer;
  • I wanted to reuse ASP.NET AJAX  for getting OO goodies.

If you take some time to look at the code, you”ll notice several things:

  • I”ve only built a control (a button) base on the button code written by Bryant Likes. I”m not a designer, so I really don”t have the skills to reproduce the looks of the remaining standard controls :(;
  • I”ve built a base class that is responsible for getting the XAML and inserting it into the parent canvas.
  • Each derived class should override the method that generates XAML
  • There are 2 methods which are called in important times on  the lifetime of the created objects (_internalHierarchyCreated is called after the createFromXaml method has been called and _internalHierarchyAddedToControl is called after the controls have been added to the child collection of the parent element)
  • You can see that I change the text shown by the textbox of one of the buttons before adding it to the control hierarchy and that”s where I set up the event handlers(take a peek at the _internalHierachyCreated method)
  • There”s a global class that is responsible for mapping each event on a specific method of the instance responsible for that event. Each control must register himself with the class to handle the necessary events for it to work properly. When I build this class, the idea was to hook up the events directly with the “static” methods. Unfortunately, Silverlight can only handle simple method names (ie, if you to set up an event with javascript:LA.Silverlight.SilverlightEventManager.dispatchLeftMouseDownEvent, it simply won”t call that method – that”s why i created the top __XXX methods).

Now that I”ve ended my available time for playing with Silverlight controls, i think that my architecture could have been improved a lot (in fact,now that I”ve finished,i really think that it kind of sucks :)). Here are some of the things I”d do if I could start over:

  • I”d create the classes as controls (instead of simple classes);
  • I”d create a canvas element that would be usable as top control;
  • I”d probably think hard to get a list of “XAML” elements that would be wrapped by Javascript classes;
  • I”d simplify event handling code. The current demo has lots  of code that could be simplified (for instance, instead of performing a pre-registration of the control with the global SilverlightEventManager object, i”d refactor that class so that it would perform event registration in  a single step);
  • I”d add xml-script support for these elements.

As a final note, I really hope that this code is obsolete by tomorrow (or by the end of MIX). If that doesn”t happen, then we”ll have lots and lots of work trying to build WPF/e controls…

Velocity Micro PC DCT/CableCARD Ready Arriving Tomorrow

My refitted screamer arrives back home tomorrow. I”m ready!

Recent Comments