WPF

Microsoft has hastily released the February 2007 CTP of the Windows Presentation Foundation Everywhere runtime. The previous CTP expired prematurely.

WPF/E is the "light" version of WPF that will run in all major browsers across several platforms (including non-Windows platform). For instance, it also works in Mozilla Firefox. Think of it as the Microsoft competitor to Flash.

WPF/E is also good at displaying video with a light-weight video engine that does not depend on Windows Media Player. Again, comparable to Flash Video, but now using the WMV format.

I noticed that the speed of the WPF/E runtime has increased significantly when compared to the December 2006 CTP.

The WPF/E samples in the Channel 9 Playground have been updated. Go check them out if you are interested in WPF/E. If you don't have WPF/E installed, your browser should prompt you on how to install the runtime.

1 Comment

[Update 2006-12-05: Changed the download location of NeaveStrobe.xaml to my new domain which serves the right mime type application/xaml+xml for .xaml files.]

Ever since I saw the Neave Strobe I wanted to create a Windows Presentation Foundation version. The original version uses Flash. The Neave Strobe is an optical illusion. Stare at the middle of the strobing lines for 20 seconds and then look away. You will be amazed at what you see.

Staring at the image below doesn't work of course, because the lines don't move 🙂

If you have the .NET Framework 3.0 installed you can view my animated WPF version: NeaveStrobe.xaml.

It doesn't work when you view this this link directly in Internet Explorer. The reason is that the web server that is hosting my XAML file, does not return the mime type application/xaml+xml for .xaml files. To work around this, download the file and save it to your local disc. Then open it in Internet Explorer.

Alternatively, you can view it in XamlPad (included in the Windows SDK). Or better, use Charles Petzold's XAML Cruncher. This program is click-once deployed to your computer if you click here.

To create the XAML file I tried using Expression Interactive Designer and "Cider". They didn't really help, so I ended up hand-coding most of it. You can see the code below:

 

<?xml version="1.0" encoding="utf-8" ?>
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    x:Name="DocumentRoot"
    WindowTitle="Neave Strobe" Width="400" Height="400">
  <Page.Resources>
    <Style TargetType="{x:Type Line}" x:Key="LineStyle">
      <Setter Property="Stroke" Value="Black"/>
      <Setter Property="StrokeThickness" Value="18"/>
    </Style>

    <Style TargetType="{x:Type Line}" x:Key="LineStyle2">
      <Setter Property="Stroke" Value="Black"/>
      <Setter Property="StrokeThickness" Value="18"/>
    </Style>

    <Style TargetType="{x:Type Canvas}" x:Key="BlockStyle">
      <Setter Property="Width" Value="200"/>
      <Setter Property="Height" Value="200"/>
    </Style>

    <Style TargetType="{x:Type Grid}" x:Key="GridSize">
      <Setter Property="Width" Value="400"/>
      <Setter Property="Height" Value="400"/>
    </Style>

    <Grid x:Key="LineGrid" RenderTransformOrigin="0.5,0.5">
      <Grid.RenderTransform>
        <TransformGroup>
          <TranslateTransform X="0" Y="0" x:Name="LineTransform" />
        </TransformGroup>
      </Grid.RenderTransform>
      <Grid.Children>
        <Line X1="-25" Y1="-25" X2="100" Y2="100"
          Style="{StaticResource LineStyle}" />
        <Line X1="25" Y1="-25" X2="150" Y2="100"
          Style="{StaticResource LineStyle}" />
        <Line X1="-75" Y1="-25" X2="50" Y2="100"
          Style="{StaticResource LineStyle}" />
        <Line X1="-125" Y1="-25" X2="0" Y2="100"
          Style="{StaticResource LineStyle}" />
        <Line X1="-175" Y1="-25" X2="-50" Y2="100"
          Style="{StaticResource LineStyle}" />
      </Grid.Children>
    </Grid>

    <Grid x:Key="LineGrid2" RenderTransformOrigin="0.5,0.5">
      <Grid.RenderTransform>
        <TransformGroup>
          <TranslateTransform X="0" Y="0" x:Name="LineTransform2" />
        </TransformGroup>
      </Grid.RenderTransform>
      <Grid.Children>
        <Line X1="-25" Y1="-25" X2="100" Y2="100"
          Style="{StaticResource LineStyle}" />
        <Line X1="25" Y1="-25" X2="150" Y2="100"
          Style="{StaticResource LineStyle}" />
        <Line X1="-75" Y1="-25" X2="50" Y2="100"
          Style="{StaticResource LineStyle}" />
        <Line X1="-125" Y1="-25" X2="0" Y2="100"
          Style="{StaticResource LineStyle}" />
        <Line X1="-175" Y1="-25" X2="-50" Y2="100"
          Style="{StaticResource LineStyle}" />
      </Grid.Children>
    </Grid>

    <VisualBrush x:Key="DiagonalLines" x:Name="DiagonalLines" 
      Viewbox="0,0,50,50" 
      ViewboxUnits="Absolute" 
      Viewport="0,0,0.1,0.1"
      ViewportUnits="RelativeToBoundingBox" 
      TileMode="Tile" 
      AlignmentX="Center"
      AlignmentY="Center"
      Visual="{StaticResource LineGrid}" />

    <VisualBrush x:Key="DiagonalLines2" x:Name="DiagonalLines2" 
      Viewbox="0,0,50,50" 
      ViewboxUnits="Absolute" 
      Viewport="0,0,0.1,0.1"
      ViewportUnits="RelativeToBoundingBox" 
      TileMode="Tile" 
      AlignmentX="Center"
      AlignmentY="Center"
      Visual="{StaticResource LineGrid2}" />

    <Storyboard x:Key="LineStoryboard" >
      <DoubleAnimation Storyboard.TargetProperty="X" BeginTime="00:00:00" 
         Storyboard.TargetName="LineTransform" 
      From="0" To="100" Duration="0:0:1" RepeatBehavior="Forever" />
      <DoubleAnimation Storyboard.TargetProperty="X" BeginTime="00:00:00" 
         Storyboard.TargetName="LineTransform2" 
      From="100" To="0" Duration="0:0:1" RepeatBehavior="Forever" />
    </Storyboard>

    <Grid x:Key="QuadLineGrid" VerticalAlignment="Top" Style="{StaticResource GridSize}">

      <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition />
      </Grid.ColumnDefinitions>
      <Grid.RowDefinitions>
        <RowDefinition />
        <RowDefinition />
      </Grid.RowDefinitions>

      <Canvas Style="{StaticResource BlockStyle}"
          Grid.Row="1" Grid.Column="1" RenderTransformOrigin="0.5,0.5" 
          Canvas.Background="{StaticResource DiagonalLines}">
        <Canvas.RenderTransform>
          <TransformGroup>
            <RotateTransform Angle="90"/>
          </TransformGroup>
        </Canvas.RenderTransform>
      </Canvas>

      <Canvas Style="{StaticResource BlockStyle}"
        Grid.Row="0" Grid.Column="1" 
        Grid.ColumnSpan="1" Grid.RowSpan="1"
        Canvas.Background="{StaticResource DiagonalLines}" />

      <Canvas Style="{StaticResource BlockStyle}"
          Grid.Row="1" Grid.Column="0" 
          Grid.ColumnSpan="1" Grid.RowSpan="1" RenderTransformOrigin="0.5,0.5"
          Canvas.Background="{StaticResource DiagonalLines}">
        <Canvas.RenderTransform>
          <TransformGroup>
            <RotateTransform Angle="180"/>
          </TransformGroup>
        </Canvas.RenderTransform>
      </Canvas>

      <Canvas Style="{StaticResource BlockStyle}"
          Grid.Row="0" Grid.Column="0" 
          Grid.ColumnSpan="1" Grid.RowSpan="1" RenderTransformOrigin="0.5,0.5" 
          Canvas.Background="{StaticResource DiagonalLines}">
        <Canvas.RenderTransform>
          <TransformGroup>
            <RotateTransform Angle="270"/>
          </TransformGroup>
        </Canvas.RenderTransform>
      </Canvas>

    </Grid>

    <Grid x:Key="QuadLineGrid2" VerticalAlignment="Top" Style="{StaticResource GridSize}">
      <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition />
      </Grid.ColumnDefinitions>
      <Grid.RowDefinitions>
        <RowDefinition />
        <RowDefinition />
      </Grid.RowDefinitions>

      <Canvas Style="{StaticResource BlockStyle}"
          Grid.Row="1" Grid.Column="1" RenderTransformOrigin="0.5,0.5" 
          Canvas.Background="{StaticResource DiagonalLines2}">
        <Canvas.RenderTransform>
          <TransformGroup>
            <RotateTransform Angle="90"/>
          </TransformGroup>
        </Canvas.RenderTransform>
      </Canvas>

      <Canvas Style="{StaticResource BlockStyle}"
          Grid.Row="0" Grid.Column="1" 
          Grid.ColumnSpan="1" Grid.RowSpan="1"
          Canvas.Background="{StaticResource DiagonalLines2}">
      </Canvas>

      <Canvas Style="{StaticResource BlockStyle}"
          Grid.Row="1" Grid.Column="0" 
          Grid.ColumnSpan="1" Grid.RowSpan="1" RenderTransformOrigin="0.5,0.5"
          Canvas.Background="{StaticResource DiagonalLines2}">
        <Canvas.RenderTransform>
          <TransformGroup>
            <RotateTransform Angle="180"/>
          </TransformGroup>
        </Canvas.RenderTransform>
      </Canvas>


      <Canvas Style="{StaticResource BlockStyle}"
          Grid.Row="0" Grid.Column="0" 
          Grid.ColumnSpan="1" Grid.RowSpan="1" RenderTransformOrigin="0.5,0.5" 
          Canvas.Background="{StaticResource DiagonalLines2}">
        <Canvas.RenderTransform>
          <TransformGroup>
            <RotateTransform Angle="270"/>
          </TransformGroup>
        </Canvas.RenderTransform>
      </Canvas>
    </Grid>

    <VisualBrush x:Key="QuadLineBrush" x:Name="QuadLineBrush"      
    Visual="{StaticResource QuadLineGrid2}" Stretch="None" />

  </Page.Resources>

  <Page.Triggers>
    <EventTrigger RoutedEvent="Canvas.Loaded">
      <BeginStoryboard Storyboard="{StaticResource LineStoryboard}">
      </BeginStoryboard>
    </EventTrigger>
  </Page.Triggers>

  <Canvas>
    <StaticResource ResourceKey="QuadLineGrid"/>
    <Ellipse Width="200" Height="200" Margin="100,100">
      <Ellipse.Fill>
        <SolidColorBrush Color="White"/>
      </Ellipse.Fill>
    </Ellipse>
    <Ellipse Width="200" Height="200" Fill="{StaticResource QuadLineBrush}" Margin="100,100" />
  </Canvas>

</Page>

Adam Nathan has a nice example of the use of animation for a property using XAML. And it's a funny post to read as well.

Two pictures of Jim Miller (one of the CLR architects) are stacked on top of each other. The animation changes the value of the opacity of the upper image from 1 (completely opaque) to 0 (completely transparant) and back again. Because the subject of the two images is the same and the two image are lined up, this gives a nice morphing effect.

I wanted to try this myself, so I searched my image archive for two similar looking photographs. I found two, but lining them up was more work than I expected. In PhotoShop I had to adjust for subtle differences in focal length, rotation, aspect ratio etc. Plus one of the photographs is one and a half year older than the other one, so the trees have grown 😉 You can see the result below.

 

To see the morph between these two pictures, paste this code into XAMLPAD

<?xml version="1.0" encoding="utf-8" ?>
<Grid xmlns="http://schemas.microsoft.com/winfx/avalon/2005">
<Grid.Storyboards>
<SetterTimeline TargetName="kerckebosch2" Path="(Image.Opacity)" AutoReverse="true" RepeatBehavior="Forever">
<DoubleAnimation From="1" To="0" Duration="0:0:4" />
</SetterTimeline>
</Grid.Storyboards>
<Image Name="kerckebosch1" Source="http://bloggingabout.net/wp-content/uploads/sites/4/2014/01/kerckebosch1.jpg"/>
<Image Name="kerckebosch2" Source="http://bloggingabout.net/wp-content/uploads/sites/4/2014/01/kerckebosch2.jpg"/>
</Grid>