Avalon: May ’05 Beta 1 RC Change Log Commentary

Here’s some quick and dirty changes I’ve noticed from the March CTP to the May Beta 1 RC. Hopefully Microsoft will post a formal change log soon:

General

  • FrameworkElement::ID property renamed FrameworkElement::Name. Subsequently any properties that used to point to a FrameworkElement by ID now point by Name (e.g. SetterTimeLine::TargetName).
  • IPropertyChanged interface renamed to INotifyPropertyChanged
  • System.Windows.Shapes.StretchableShape base class introduced to add support for Shape stretching in layout managers that support Horizontal/VerticalAlignment.
  • Geometry::DoesContainWithDetail renamed to Geometry::ContainsWithDetail
  • TransformGroup class introduced for composing transforms. You specify this anywhere you used to specify a TransformCollection.
  • System.Windows.Media.Imaging namespace introduced for all things that have to do with bitmap style graphics. Classes such as BitmapSource and BitmapDecoder have been moved here along with other related classes.
  • System.Windows.Threading updated to cooporate with .NET’s System.Threading.SynchronizationContext. What does this mean? Well for one, people can write one set of synchronization code for WinForms and Avalon apps using the abstract class. Admittedly, most people aren’t going to do that. The more immediate benefit of this change to most people is that BackgroundWorker, which is based on this abstract architecture, now works for Avalon applications too!
  • TransformDecorator removed, replaced by FrameworkElement::LayoutTransform property.
  • IAnimatable::GetAnimations changed to IAnimatable::PersistentAnimations.

Styles

New syntax for styling using “Setters”:

<Style x:Key="MyStyle">
  <Style.Setters>
    <Setter Property="Control.Foreground" Value="Blue"/>


<!-- or, for complex properties -->
<Setter Property="Control.Background">
<Setter.Value>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
<LinearGradientBrush.GradientStops>
<GradientStop Color="White" Offset="0"/>
<GradientStop Color="Yellow" Offset="1"/>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Setter.Value>
</Setter> </Style.Setters>
</Style>

This is a pretty fundamental change and a good one if you ask me. Basically what they’re doing is getting rid of the “inline typing” syntax. To accomplish the following older syntax:

<Style>
    <Button Background="Green"/>
</Style>

You now do this:

<Style TargetType="{x:Type Button}">
<Style.Setters>
     <Setter Property="Button.Background" Value="Green"/>
</Style.Setters>
</Style>

The other major change to styles is the removal of Style.VisualTree. This concept is replaced by a new one called FrameworkTemplate. For Controls, a template is assigned via the Control::Template property. To acheive the following older syntax:

<Style>
<Button/>
<Style.VisualTree>
<Grid>
<Rectangle Fill="*Alias(Target=Background)" RadiusX="10" RadiusY="10"/>
<TextBlock TextContent="*Alias(Target=Content)"
Foreground="*Alias(Target=Foreground)"
HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
</Style.VisualTree>
</Style>

You now do this:

<StackPanel>
<StackPanel.Resources>
   <ControlTemplate x:Key="MyButtonTemplate">
     <Grid Binding.DataContext="{Binding RelativeSource=/TemplatedParent}">
      <Rectangle Fill="{Binding Path=Background}"
RadiusX="10" RadiusY="10"/>
      <TextBlock TextContent="{Binding Path=Content}"
Foreground="{Binding Path=Foreground}"
HorizontalAlignment="Center" VerticalAlignment="Center" />
     </Grid>
    </ControlTemplate>
    <Style TargetType="{x:Type Button}">
    <Style.Setters>
     <Setter Property="Control.Template" Value="{StaticResource MyButtonTemplate}"/>
     </Style.Setters>
   </Style>
  </StackPanel.Resources>
<StackPanel>
  <Button Background="Red" Foreground="White">Red</Button>
  <Button Background="Green" Foreground="White">Green</Button>
  <Button Background="Blue" Foreground="White">Blue</Button>
  <Button Background="Yellow" Foreground="Black">Yellow</Button>
</StackPanel>
</StackPanel>

This example also shows the new Binding syntax used in templates which replaces the old *Alias approach. The syntax uses a special value for the RelativeSource: “/TemplatedParent”.

MarkupExtension Changes

  • The “Bind” markup extension was renamed to “Binding”.
  • *Alias magic finally gone, replaced by Binding with RelativeSource=/TemplatedParent (see Styles section for sample).
  • ArrayExtension, ResourceKey and TemplateBindingExtension introduced

8 thoughts on “Avalon: May ’05 Beta 1 RC Change Log Commentary

  1. What is the setter syntax for complex objects? What to do for backgrounds that are LinearGradientBrush with a collection of stops for example? I will have to dig into the new SDK to locate this one.

  2. Michael,

    Thanks for pointing this out. I’ll have to add a note about this, but the answer right now seems to be that you would use the shorthand syntax in the Value attribute. I thought maybe you would just nest the <LinearGradientBrush> in the <Setter>, but that doesn’t work.

    Cheers,
    Drew

  3. TransportDecorator removed! (TransportDecorator is now xxx.LayoutTransform)

    xxx.RenderTransform (no layout affected)
    xxx.LayoutTransform (layout affected)

    Sample 1 (RenderTransform):

    <StackPanel>
    <Button>
    <Button.RenderTransform>
    <RotationTransform Angle=”45″/>
    </Button.RenderTransform>
    A Button 1
    </Button>
    <Button>A Button 2</Button>
    </StackPanel>

    Note: button 2 not affected by button 1

    Sample 2 (LayoutTransform):

    <StackPanel>
    <Button>
    <Button.LayoutTransform>
    <RotationTransform Angle=”45″/>
    </Button.LayoutTransform>
    A Button 1
    </Button>
    <Button>A Button 2</Button>
    </StackPanel>

    Note: button 2 is affected by button 1

  4. <ContentPresenter Content=”{Binding Path=Content}”/>

    I get a ArgumentException: “Binding for property ‘Content’ must use an
    explicit source. Parameter name: dp”

    How to use ContentPresenter on ControlTemplate?

    Tks

Leave a Reply