Skip to content
Bruno Sonnino
Menu
  • Home
  • About
Menu

Animating transitions in WPF/Silverlight–Part II–Using Components

Posted on 7 February 2012

In the last post we saw how to animate a transition using code. As I said, I don’t think that is the best solution, because we must use code behind, something not easy to maintain. We could refactor code, creating a new class for the animation and use it. That would bring a little more separation, but we would have to still use code behind.

In this second part, we will use a different approach: third party components. We can use several components, like Kevin Bag-O-Tricks (https://github.com/thinkpixellab/bot), FluidKit (http://fluidkit.com), Silverlight Toolkit (http://silverlight.codeplex.com – only for Silverlight), or Transitionals (http://transitionals.codeplex.com).

We will use here Transitionals, for WPF. If we want to do animations for Silverlight, we should choose another component. Its use is very simple: after downloading the component and adding a reference in the project to the Transitionals.dll assembly, we must add a TransitionElement component in the place where we want the animation, configure the animation and add a content to the component. When the content is changed, the transition is activated.

Let’s create our transition project. Create a new WPF project and add a reference to Transitionals.dll. Then, add a TransitionElement to the main grid:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*" />
        <RowDefinition Height="40" />
    </Grid.RowDefinitions>
    <transc:TransitionElement x:Name="TransitionBox">
    <transc:TransitionElement.Transition>
    <transt:TranslateTransition  StartPoint="1,0" EndPoint="0,0" Duration="0:0:1"/>
    </transc:TransitionElement.Transition>
    </transc:TransitionElement>
    <Button Width="65" Grid.Row="1" Content="Hide" Margin="5" Click="Button_Click" />
</Grid>
XML

We must declare the namespaces for the TransitionElement and for the TranslateTransition in the main window:

<Window x:Class="WpfApplication2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:transc="clr-namespace:Transitionals.Controls;assembly=Transitionals"
        xmlns:transt="clr-namespace:Transitionals.Transitions;assembly=Transitionals"
        Title="MainWindow" Height="350" Width="525">
XML

The next step is to add content to the TransitionElement:

<transc:TransitionElement x:Name="TransitionBox">
    <transc:TransitionElement.Transition>
        <transt:TranslateTransition  StartPoint="1,0" EndPoint="0,0" Duration="0:0:1"/>
    </transc:TransitionElement.Transition>
    <Grid Background="Red" />
</transc:TransitionElement>
XML

The button click event handler changes the content of the TransitionElement and activates the transition:

private void Button_Click(object sender, RoutedEventArgs e)
{
    TransitionBox.Content = new Grid() {Background = Brushes.Blue};
}
C#

That way, the code is simpler, we just need to change the content of the element. Besides that, the Transitionals component has a lot of transition types, and we can set them in many ways. For example, the TranslateTransition has the properties StartPoint and EndPoint, saying where the transition starts and ends. To do it from left to right, StartPoint should be –1,0 and EndPoint, 0,0. From top to bottom, StartPoint should be 0,-1 and EndPoint, 0, 0. We can even do a diagonal transition using 1,1 and 0,0.

Eliminating Code Behind

One thing that can be improved here is the elimination of code behind, using the MVVM pattern. We will use the MVVM Light framework, that you can get at http://galasoft.ch or by installing it directly using NuGet, an add-in to Visual Studio to ease download and installation of libraries and tools in Visual Studio. If you still don’t have NuGet, go to http://nuget.org and download it. Once you have installled NuGet, you can click with the right button in References in the Solution Explorer and select “Manage Nuget Packages”. Fill the search box with “mvvm” and install the MVVM Light package:

This installs MVVM Light, adds the required references and creates a folder named ViewModel, with two files, MainViewModel.cs and ViewModelLocator.cs. MainViewModel.cs is the ViewModel related to the main window and ViewModelLocator is a ViewModel locator. In MainViewModel.cs you should add a property of type ViewModelBase, which will contain the ViewModel related to the View of the component content:

private ViewModelBase content;

public ViewModelBase Content
{
    get { return content; }
    set
    {
        conteudo = value;
        RaisePropertyChanged("Content");
    }
}
C#

Next, we will create two ViewModels, related to our views. The two ViewModels are very similar and have only one property:

public class ViewModelA : ViewModelBase
{
    private string text;

    public string Text
    {
        get { return text; }
        set
        {
            text = value;
            RaisePropertyChanged("Text");
        }
    }
}

public class ViewModelB : ViewModelBase
{
    private string text;

    public string Text
    {
        get { return text; }
        set
        {
            text = value;
            RaisePropertyChanged("Text");
        }
    }
}
C#

Then create in the Solution Explorer a folder named View and put there two UserControls, each one with a Grid and a TextBlock:

<UserControl x:Class="WpfApplication2.View.ViewA"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <Grid Background="Red">
        <TextBlock Text="{Binding Text}" FontSize="36" />
    </Grid>
</UserControl>
XML

To eliminate code behind, we must bind the property Content of the TransitionElement with the property Content of the ViewModel:

<transc:TransitionElement x:Name="TransitionBox" Content="{Binding Content}">
    <transc:TransitionElement.Transition>
        <transt:TranslateTransition  StartPoint="1,0" EndPoint="0,0" Duration="0:0:1"/>
    </transc:TransitionElement.Transition>
</transc:TransitionElement>
XML

and eliminate the button click, replacing it with a Command:

<Button Width="65" Grid.Row="1" Content="Esconde" Margin="5" Command="{Binding HideCommand}" />
C#

The HideCommandproperty is defined in MainViewModel:

private ICommand hideCommand;
public ICommand HideCommand
{
    get { return hideCommand ?? (hideCommand = new RelayCommand(ChangeContent)); }
}

private void ChangeContent()
{
    Content = content is ViewModelA ? 
        (ViewModelBase)new ViewModelB() {Text = "ViewModel B"} : 
        (ViewModelBase)new ViewModelA() {Text = " ViewModel A"};
}
C#

Finally we must set the DataContext for the main View:

<Window x:Class="WpfApplication2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:transc="clr-namespace:Transitionals.Controls;assembly=Transitionals"
        xmlns:transt="clr-namespace:Transitionals.Transitions;assembly=Transitionals" 
        Title="MainWindow" Height="350" Width="525"
        DataContext="{Binding Source={StaticResource Locator}, Path=Main}">
XML

When we execute the program we have something similar to this:

The view isn’t shown, just the content’s class name. That is expected, as the property Content is of type ViewModelBase and its presentation is made by the method ToString(). We could have put the view as content, but this goes against the MVVM pattern: the ViewModel must not know about the View. A solution to show the View using the ViewModel as content is to use a resource available in WPF or in Silverlight 5: implicit Data Templates. In an implicit DataTemplate, we don’t set the Key property when declaring the Template, we only set its DataType. With that, WPF and Silverlight use this DataTemplate every time they must render some content of that type. We declare the DataTemplates in the Windows’s resources section:

<Window.Resources>
    <DataTemplate DataType="{x:Type ViewModel:ViewModelA}" >
        <View:ViewA />
    </DataTemplate>
    <DataTemplate DataType="{x:Type ViewModel:ViewModelB}" >
        <View:ViewB />
    </DataTemplate>
</Window.Resources>
XML

Now, when we execute the program, we have the transition between the two views, with no code behind.

Conclusion

When we use components to animate transitions, we have the possiblity to create very complex transitions in an easy way, we only have to change the content of the control. We also saw how to remove code from the code behind, adding it to a ViewModel, making it easier to maintain and allowing better testability. As a bonus, we saw how to use implicit DataTemplates and how to relate a View to a ViewModel with no need of code. This resource is only available on WPF and Silverlight 5. Although you can think it doesn’t worth the effort (we eliminated just one line of code, trading it with two ViewModels, two Views and a new MVVM component), my intent here was to show you other resources, like using MVVM instead of code behind and how to use new features, like the implicit DataTemplate. In a larger application, that requires more work, these changes are justified. These are not the only ways to do control transitions. On the next articles, we will see other ways. See you then!

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

  • May 2025
  • December 2024
  • October 2024
  • August 2024
  • July 2024
  • June 2024
  • November 2023
  • October 2023
  • August 2023
  • July 2023
  • June 2023
  • May 2023
  • November 2022
  • October 2022
  • September 2022
  • August 2022
  • June 2022
  • April 2022
  • March 2022
  • February 2022
  • January 2022
  • July 2021
  • June 2021
  • May 2021
  • April 2021
  • March 2021
  • February 2021
  • January 2021
  • December 2020
  • October 2020
  • September 2020
  • April 2020
  • March 2020
  • January 2020
  • November 2019
  • September 2019
  • August 2019
  • July 2019
  • June 2019
  • April 2019
  • March 2019
  • February 2019
  • January 2019
  • December 2018
  • November 2018
  • October 2018
  • September 2018
  • August 2018
  • July 2018
  • June 2018
  • May 2018
  • November 2017
  • October 2017
  • September 2017
  • August 2017
  • June 2017
  • May 2017
  • March 2017
  • February 2017
  • January 2017
  • December 2016
  • November 2016
  • October 2016
  • September 2016
  • August 2016
  • July 2016
  • June 2016
  • May 2016
  • April 2016
  • March 2016
  • February 2016
  • October 2015
  • August 2013
  • May 2013
  • February 2012
  • January 2012
  • April 2011
  • March 2011
  • December 2010
  • November 2009
  • June 2009
  • April 2009
  • March 2009
  • February 2009
  • January 2009
  • December 2008
  • November 2008
  • October 2008
  • July 2008
  • March 2008
  • February 2008
  • January 2008
  • December 2007
  • November 2007
  • October 2007
  • September 2007
  • August 2007
  • July 2007
  • Development
  • English
  • Português
  • Uncategorized
  • Windows

.NET AI Algorithms asp.NET Backup C# Debugging Delphi Dependency Injection Desktop Bridge Desktop icons Entity Framework JSON Linq Mef Minimal API MVVM NTFS Open Source OpenXML OzCode PowerShell Sensors Silverlight Source Code Generators sql server Surface Dial Testing Tools TypeScript UI Unit Testing UWP Visual Studio VS Code WCF WebView2 WinAppSDK Windows Windows 10 Windows Forms Windows Phone WPF XAML Zip

  • Entries RSS
  • Comments RSS
©2025 Bruno Sonnino | Design: Newspaperly WordPress Theme
Menu
  • Home
  • About