Animations: Sliding & Fading controls on a C# form (winforms)
Asked Answered
G

5

16

I'm trying to implement a way to animate (translate, fade) controls around (more than one at the same time possibly) elegantly. For example, lets say I had a picture in the top left corner, and a textbox in the bottom right corner, I'd like to be able to have them smoothly slide across the window and switch places. I've been working for awhile but have not come up with anything that achieves this smoothly or easily.

Greasewood answered 27/5, 2010 at 1:22 Comment(0)
S
24

Check out the dot-net-transitions project on Google Code. There's now a clone on Github here. It's also available on nuget as dot-net-transitions. It supports a variety of linear/non-linear transitions including composite transitions that can be used for more complex effects such as ripple.

Here is a working sample that demonstrates your desired behavior:

var pictureBox = new PictureBox
    {
        ImageLocation = "http://icons2.iconarchive.com/icons/klukeart/summer/128/hamburger-icon.png",
        SizeMode = PictureBoxSizeMode.AutoSize
    };
var textBox = new TextBox
    {
        Text = "Hello World",
        Location = new Point(140, 140)
    };
var form = new Form
    {
        Controls =
        {
            textBox,
            pictureBox
        }
    };
form.Click += (sender, e) =>
    {
        // swap the Left and Top properties using a transition
        var t = new Transition(new TransitionType_EaseInEaseOut(1000));
        t.add(pictureBox, "Left", textBox.Left);
        t.add(pictureBox, "Top", textBox.Top);
        t.add(textBox, "Left", pictureBox.Left);
        t.add(textBox, "Top", pictureBox.Top);
        t.run();
    };
form.ShowDialog();
Singular answered 27/5, 2010 at 1:53 Comment(0)
B
8

I recommend that you switch to WPF; that would make it far easier.

It is completely impossible to fade controls in WinForms; Windows controls cannot have opacity.
The closest you can get would be to render the control and its area on the form to a pair of bitmaps, then crossfade the bitmaps in a PictureBox using a ColorMatrix.

To slide controls in WinForms, you can use a Timer to gradually change the Top and/or Left properties of the controls and move them across the form. However, you'll get an annoying flicker, which is (AFAIK) impossible to remove.

Besought answered 27/5, 2010 at 1:25 Comment(1)
For future reference: this.Update(); just outside of the moveControl method you create will dramatically reduce flickering, practically to the point where it's not noticable unless you're running like a billion apps at once.Narrowminded
R
2

You could do this in WinForms, with a great deal of effort, so I would have to second the recommendations to use WPF (which is essentially built for exactly this kind of thing).

Your main obstacle to doing this in WinForms is the fact that a control location is specified by integer, which means you can't set a control's Left property to 45.3425, for example. This basically makes smooth animation of controls (assuming you want movement that changes speeds and directions) completely impossible - you will get an unavoidable jerkiness of movement this way (I've tried, so I know).

As SLaks suggested, the only way to do this in WinForms would be to "fake" it by taking "snapshots" of each control. Basically, you would start with an invisible Bitmap the size of your form, drawn with the form's BackColor. You would then create the "snapshots" by calling DrawToBitmap() on each control you wish to animate, and create the movement effect by drawing the snapshots onto the canvas (System.Drawing can draw images with floating-point coordinates, avoiding the jerkiness of integer locations).

This is too much damn work, though. Just use WPF. :)

Edit: I should mention that it's actually easy to do something like this in WinForms, as long as you don't mind it looking awful and jerky and amateurish. My above comments refer to the difficulties of doing this well.

Rossini answered 27/5, 2010 at 1:56 Comment(0)
E
0

Save a copy of each of the items' x and y values as a float.

Use a timer, and upon each tick add a value to the top left item's x and y position. Subtract the same value from the bottom right item's x and y.

Make sure you use the cached float values here, otherwise you might get rounding errors when the item is relocated on the form.

If you're painting on whatever surface you're using for images/controls, invalidate it for each tick.

Should be easy-peasy.

Edit:

For transparent controls, check out Bob Powell's Tips & Tricks:

https://web.archive.org/web/20141227200000/http://bobpowell.net/transcontrols.aspx

And here is his own reply on how to make semitransparent controls:

http://www.mofeel.net/67-microsoft-public-dotnet-framework-windowsforms-controls/4860.aspx

Eristic answered 27/5, 2010 at 1:31 Comment(2)
Huh? Neither link shows how to make semitransparent controls.Rossini
The first link is a great tutorial on how to create fully transparent controls. The second link is a short discussion on how you could create semitransparent controls by using your own custom painting with brushes with an alpha value. It also mentions the caveat that this kind of solution might cause flicker. Bob Powell furthermore hints in the direction that such a control could be achieved by using the LayeredWindow API. In any case, depending on Tommy's requirements, doing this in WinForms might be tricky.Eristic
O
0

I believe that this answer of using builtin AnimateWindow is much better for this purpose: How can I add moving effects to my controls in C#?

Ornelas answered 19/1, 2013 at 1:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.