WPF FAQ - Serialization and Storage

How can I animate a BorderThickness value ?

BorderThickness can be animated by using the ‘ThicknessAnimation’ class.

The following example animates the thickness of a border by using the ThicknessAnimation. The example uses the ‘BorderThickness’ property of Border.

[XAML]

<!-- This example shows how to use the ThicknessAnimation to create
an animation on the BorderThickness property of a Border. -->
<Page  xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'
  xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml' >

  <StackPanel Orientation='Vertical' HorizontalAlignment='Center'>
    <Border Background='#99FFFFFF' BorderBrush='#CCCCFF' BorderThickness='1'
    Margin='0,60,0,20' Padding='20'  >
      <Border.Triggers>
        <EventTrigger RoutedEvent='Border.Loaded'>
          <BeginStoryboard>
            <Storyboard>

              <!-- BorderThickness animates from left=1, right=1, top=1, and bottom=1 to
              left=28, right=28, top=14, and bottom=14 over one second. -->
              <ThicknessAnimation
                Storyboard.TargetProperty='BorderThickness'
                Duration='0:0:1.5' FillBehavior='HoldEnd' From='1,1,1,1' To='28,14,28,14' />
            </Storyboard>
          </BeginStoryboard>
        </EventTrigger>
      </Border.Triggers>
      <TextBlock>
        This example shows how to use the ThicknessAnimation to create
        an animation on the BorderThickness property of a Border.
      </TextBlock>
    </Border>
  </StackPanel>
</Page>
Permalink
How do I create a Borderless Window in WPF ?

To make the window display without this gray border, you need to set the ‘ResizeMode’ property of the window to ’NoResize’.

[XAML]
<Window x:Class='BorderlessWindow.Window1'
 xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'
 xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
 Title='BorderlessWindow' Height='200' Width='200' 
 Background='White' WindowStyle='None' ResizeMode='NoResize'>
 <Border Padding='5' BorderBrush='#feca00' 
	 BorderThickness='3' Width='150' Height='150'>
 <TextBlock>Learn WPF!</TextBlock>
 </Border>
</Window>
Permalink
How can I do versioning using Custom Serialization ?

Versioning can be done using serialization as follows.

[C#]
//Version 2.0.0.0
[Serializable]
public class MyClass : ISerializable
{
   public int Number;
   public int NewField;
   
   public void GetObjectData(
       SerializationInfo info,StreamingContext context)
   {
      info.AddValue('Number',Number);      
      info.AddValue('NewField',NewField);
   }

   protected MyClass(SerializationInfo info,StreamingContext context)
   {
      Number = info.GetInt32('Number');
      Version storedVersion = SerializationUtil.GetVersion(info);
      if(storedVersion.ToString() == '2.0.0.0')
      {
         NewField = info.GetInt32('NewField');
      }
      else
      {
         NewField = 123;//Some default value
      }
   }

   public MyClass()
   {}
}

public static class SerializationUtil
{
   static public Version GetVersion(SerializationInfo info)
   {
      string assemblyName = info.AssemblyName;
      /* AssemblyName is in the form of 'MyAssembly, Version=1.2.3.4,  
                              Culture=neutral,PublicKeyToken=null' */
      char[] separators = {’,’,’=’};
      string[] nameParts = assemblyName.Split(separators);
      return new Version(nameParts[2]);
   }
   //Rest of SerializationUtil
}
Permalink
How can I use MemoryStream to create a deep clone of a serializable object ?

This can be done as follows.

[C#]

public static class SerializationUtil
{
   static public T Clone<t>(T source)
   {
      Debug.Assert(typeof(T).IsSerializable);

      IGenericFormatter formatter = new GenericBinaryFormatter(); 
      Stream stream = new MemoryStream(); 
      formatter.Serialize(stream,source);
      stream.Seek(0,SeekOrigin.Begin);

      T clone = formatter.Deserialize<t>(stream);
      stream.Close(); 
      return clone;
   }
//Rest of SerializationUtil
}
</t></t>
Permalink
How can I store a given document in a specific format using CreateSerializerWriter methods ?

You can store a given document format using CreateSerializerWriter method as follows.

[C#]

// Create a SerializerProvider for accessing plug-in serializers.
SerializerProvider serializerProvider = new SerializerProvider();

// Locate the serializer that matches the fileName extension.
SerializerDescriptor selectedPlugIn = null;
foreach ( SerializerDescriptor serializerDescriptor in
                serializerProvider.InstalledSerializers )
{
    if ( serializerDescriptor.IsLoadable &&
         fileName.EndsWith(serializerDescriptor.DefaultFileExtension) )
    {   // The plug-in serializer and fileName extensions match.
        selectedPlugIn = serializerDescriptor;
        break; // foreach
}
}

// If a match for a plug-in serializer was found,
// use it to output and store the document.
if (selectedPlugIn != null)
{
    Stream package = File.Create(fileName);
    SerializerWriter serializerWriter =
        serializerProvider.CreateSerializerWriter(selectedPlugIn,
                                                  package);
    IDocumentPaginatorSource idoc =
        flowDocument as IDocumentPaginatorSource;
    serializerWriter.Write(idoc.DocumentPaginator, null);
    package.Close();
    return true;
}
Permalink
How can I use Event Trigger to control a StoryBoard after it is started ?

The following example uses controllable storyboard actions to interactively control a storyboard.

[XAML]

<Page xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'
  xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
  WindowTitle='Controlling a Storyboard' >
  <StackPanel Margin='20' >

    <!-- This rectangle is animated. -->
    <Rectangle Name='myRectangle'
      Width='100' Height='20' Margin='12,0,0,5' Fill='#AA3333FF' HorizontalAlignment='Left' />

    <!-- This StackPanel contains all the Buttons. -->
    <StackPanel Orientation='Horizontal' Margin='0,30,0,0'>

      <Button Name='BeginButton'>Begin</Button>
      <Button Name='PauseButton'>Pause</Button>
      <Button Name='ResumeButton'>Resume</Button>
      <Button Name='SeekButton'>Seek</Button>
      <Button Name='SkipToFillButton'>Skip To Fill</Button>
      <Button Name='SetSpeedRatioButton'>Triple Speed</Button>
      <Button Name='StopButton'>Stop</Button>

      <StackPanel.Triggers>

        <!-- Begin the Storyboard -->
        <EventTrigger RoutedEvent='Button.Click' SourceName='BeginButton'>
          <BeginStoryboard Name='MyBeginStoryboard'>
            <Storyboard >
              <DoubleAnimation 
                Storyboard.TargetName='myRectangle' 
                Storyboard.TargetProperty='Width' 
                Duration='0:0:5' From='100' To='500' />
            </Storyboard>
          </BeginStoryboard>
        </EventTrigger>

        <!-- Pause the Storyboard -->
        <EventTrigger RoutedEvent='Button.Click' SourceName='PauseButton'>
          <PauseStoryboard BeginStoryboardName='MyBeginStoryboard' />
        </EventTrigger>

        <!-- Resume the Storyboard -->
        <EventTrigger RoutedEvent='Button.Click' SourceName='ResumeButton'>
          <ResumeStoryboard BeginStoryboardName='MyBeginStoryboard' />
        </EventTrigger>

         <!-- Seek one second into the storyboard’s active period. -->
         <EventTrigger RoutedEvent='Button.Click' SourceName='SeekButton'>
           <SeekStoryboard 
            BeginStoryboardName='MyBeginStoryboard' 
            Offset='0:0:1' Origin='BeginTime' />
        </EventTrigger>   

        <!-- Skip to Fill -->
        <EventTrigger RoutedEvent='Button.Click' SourceName='SkipToFillButton'>
          <SkipStoryboardToFill BeginStoryboardName='MyBeginStoryboard' />
        </EventTrigger>

        <!-- Stop the Storyboard -->
        <EventTrigger RoutedEvent='Button.Click' SourceName='StopButton'>
          <StopStoryboard BeginStoryboardName='MyBeginStoryboard' />
        </EventTrigger>

        <!-- Triple the speed of the Storyboard -->
        <EventTrigger RoutedEvent='Button.Click' SourceName='SetSpeedRatioButton'>
          <SetStoryboardSpeedRatio SpeedRatio='3' BeginStoryboardName='MyBeginStoryboard' />
        </EventTrigger>
      </StackPanel.Triggers>
    </StackPanel>
  </StackPanel>
</Page>
Permalink