Simple wpf animation

We can combine a couple of animations, expanding the width of a grid and translating it to the left.

expandermove

Since it is a GUI effect, we can write in the code behind.

The need to add the TranslateTransform stems from the fact that the grid would expand its width toward the right otherwise. Please comment back if you deem there is a different and simpler solution, anyway this is obviously only an example to learn the basic operations.

public partial class Window1 : Window
{
	public Window1()
	{
		InitializeComponent();
	}
	bool isOpen = false;
	void btnOpen_Click(object sender, RoutedEventArgs e)
	{
		btnOpen.IsEnabled=false;
		var group = new TransformGroup();
		var scale = new ScaleTransform();
		var translate = new TranslateTransform();
		group.Children.Add(scale);
		group.Children.Add(translate);
		gridPanel.RenderTransform = group;
		double start_width=50;
		double end_width=300;
		var targetScale =  end_width/start_width;
		var targetTranslate = start_width-end_width;
		var animScale = new DoubleAnimation((isOpen ? targetScale : 1),
		                                (isOpen ? 1 : targetScale),
		                                TimeSpan.FromSeconds(1.2));
		var animTranslate = new DoubleAnimation((isOpen ? targetTranslate : 0),
		                                (isOpen ? 0 : targetTranslate),
		                                TimeSpan.FromSeconds(1.2));
		animScale.Completed += animate_Completed;
		scale.BeginAnimation(ScaleTransform.ScaleXProperty,animScale);
		translate.BeginAnimation(TranslateTransform.XProperty, animTranslate);
	}
	private void animate_Completed(object sender, EventArgs e)
	{
		isOpen = !isOpen;
		btnOpen.Content = isOpen ? "Close" : "Open";
		btnOpen.IsEnabled=true;
	}
}

 More realistic

Let’s do a little update in order to make the example more realistic.

We want to start from an opened panel so that we can easily define it in the editor.

move

Also because we will hide the rescaled version.

public partial class Window1 : Window
{
	public Window1()
	{
		InitializeComponent();
	}
	bool isOpen = true;
	void btnOpen_Click(object sender, RoutedEventArgs e)
	{
		btnOpen.IsEnabled=false;
		gridPanel.Visibility = Visibility.Visible;
		var group = new TransformGroup();
		var scale = new ScaleTransform();
		var translate = new TranslateTransform();
		group.Children.Add(scale);
		group.Children.Add(translate);
		gridPanel.RenderTransform = group;
		const double start_width = 900;
		const double end_width = 50;
		const double seconds =0.9;
		const double targetScale = end_width / start_width;
		const double targetTranslate = start_width - end_width;
		var animScale = new DoubleAnimation((isOpen ? 1 : targetScale),
		                                    (isOpen ?  targetScale : 1),
		                                TimeSpan.FromSeconds(seconds));
		var animTranslate = new DoubleAnimation((isOpen ? 0 : targetTranslate),
		                                        (isOpen ? targetTranslate : 0),
		                                TimeSpan.FromSeconds(seconds));
		animScale.Completed += animate_Completed;
		scale.BeginAnimation(ScaleTransform.ScaleXProperty, animScale);
		translate.BeginAnimation(TranslateTransform.XProperty, animTranslate);
	}
	private void animate_Completed(object sender, EventArgs e)
	{
		isOpen = !isOpen;
		btnOpen.Content = isOpen ? "Close" : "Open";
		gridPanel.Visibility = isOpen ? Visibility.Visible : Visibility.Collapsed;
		btnOpen.IsEnabled=true;
	}
}
Advertisements

11 thoughts on “Simple wpf animation

  1. To start with, I really like the example, as it is simple enough in such a way that we can get fast to the point being addressed, and at the same time, it is complex enough to demonstrate something not trivial that is meaningful in the real world of development.

    As nowadays XAML markup is really powerful, the example could be (re)written with just all the transform stuff into XAML: each of the transforms that form the Transform Group, group that ends up assigned to the RenderTransform, everything in XAML format.

    It would be something of the form:

    But I would still include in the example some code-behind stuff … it would make sense to use code-behind for the “magic” it can bring to the mix, like for instance, for some very late bound action, that could be anything animation-related, or even something related to some other part of the user story, something “functional”.

    Let suppose that you have to develop the UI of an application for the emergency rooms of hospital or a clinic, where most out-patients are given some basic medical care and released, but on occasion, an out-patient needs to be converted into a registered patient.

    In this case, your original instance has to change of class, with the class out-patient and registered-patient both inheriting from a base class, like say BasePatient.

    You have two parallel trees of classes that are related: the tree of functional classes, and the tree of XAML forms for the UI of the CRUD of instances of said functional tree.

    In our specifc case at the ER, you have to change classes on the fly, and even though you could convert the instance of out-patient into an equivalent instance of registered-patient, it does not make sense to do the same with the UI, as you are already within an instance of a form for out-patient CRUD operations: it would make sense to convert on the fly, like with very late bound Decorators or something of the sort.

    Kind regards, GEN

    Liked by 1 person

    • Thank you for the great idea. I need some time to elaborate it. At the moment I’ve only done a stupid update because I want to be able to define the xaml using the classical gui tools. Well, I guess I have to write another post about the conversion “on the fly” you are mentioning. Maybe in F#, let me think…

      Like

    • Yes, I think there is a bug in wordpress because also I could not do that in the post (there is an image only for the xaml). I am going to share on github so that we can follow up there. Wait 5 minutes

      Like

  2. Giulio,

    Regarding the problem you are facing with EPPlus handling Excel workbooks with complex Pivot Tables, if you can´t wait for the roadmap (of EPPlus) to implement/fix said bug, I would check if other libraries, like Closed XML could handle what you need with Pivot Tables.

    I know and undestand that it is not a “good” design decision to mix libraries of similar function on a given solution, but at the same time, it is as clear as water that we all have to deliver working code within a timeframe, usually, a short one.

    Any given class may participate in a series of collaboration diagrams (from an UML perspective), with each collab diagram being a society of classes.

    On a given collab diagram, a given class participates on a given role. For any given class in a solution, there are sets of functionally related collab diagrams where said class plays a given role, and the semantics involved in those roles for said class could be properly encapsulated and expressed with an interface.

    So, for any given class, interfaces are projections to that class.

    But from the perspective of the collab diagram and in particular, from the perspective of the components that uses a given class, they see the semantics and the projections, the interfaces, and they never really see the classes in the open (there is always some factory scheme that hides the instantiation decisions from the consumer classes)

    It is from this perspective, the viewpoint of the consumer components, where you could combine similar libraries if it is required, at least for a while.

    Since the consumer components only consume a given interface with a given semantic, as an architect you are free to change in the future which library does the heavy lifting behind the interface, as long as you keep the interface and the semantics, that is, as long as you stick to the contract.

    I am not certain that Closed XML could solve what you have at hand with those complex Pivot Tables, but all it takes is just a spike or two to figure out whether or not it does work.

    I hope this is helpful.

    Kind regards, GEN

    Like

    • Hi!
      No worries, yes, the point is that I’ve received a file containing too many and too complex pivot tables, for which there is really no lib available. But it’s ok, I’ve already explained the situation to the client and we’ve agreed a much more reasonable xlsx (for which I can use closedxml as usual). It has been an interesting experience, anyway, to make a new connection on github and also thanks for your comment here. Yes, I prefer the wpf animations instead of the excel pivot 😉 … Cheers!

      Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s