I would like to 'shake' my winforms form to provide user feedback, much like the effect used on a lot of mobile OS's.
I can obviously set the location of the window and go back and forth with Form1.Location.X
etc. but the effect from this method is terrible. I'd like something a little more fluent - or alternatively is there a way to shake the entire screen?
I'll only be targeting Windows 7 using .net 4.5.
Update
Using both Hans and Vidstige suggestions I've come up with the following, which also works when the window is maximized - I wish I could pick two answers, I've up-voted your answer though Vidstige and hope others will too. Hans' answer hits all the salient points though.
Two forms MainForm
and ShakeForm
Private Sub shakeScreenFeedback()
Dim f As New Shakefrm
Dim b As New Bitmap(Me.Width, Me.Height, PixelFormat.Format32bppArgb)
Me.DrawToBitmap(b, Me.DisplayRectangle)
f.FormBorderStyle = Windows.Forms.FormBorderStyle.None
f.Width = Me.Width
f.Height = Me.Height
f.ShowInTaskbar = False
f.BackgroundImage = b
f.BackgroundImageLayout = ImageLayout.Center
f.Show(Me)
f.Location = New Drawing.Point(Me.Location.X, Me.Location.Y)
'I found putting the shake code in the formLoad event didn't work
f.shake()
f.Close()
b.Dispose()
End Sub
Public Sub shake()
Dim original = Location
Dim rnd = New Random(1337)
Const shake_amplitude As Integer = 10
For i As Integer = 0 To 9
Location = New Point(original.X + rnd.[Next](-shake_amplitude, shake_amplitude), original.Y + rnd.[Next](-shake_amplitude, shake_amplitude))
System.Threading.Thread.Sleep(20)
Next
Location = original
End Sub
The typical problem is having way too many controls on the form, making the painting too slow. So just fake it, create a borderless window that displays a bitmap of the form and shake that one. Create the bitmap with the form's DrawToBitmap() method. Use 32bppPArgb for the pixel format, it draws ten times faster than all the other ones.
Have you tried something like this?
private void shakeButton_Click(object sender, EventArgs e)
{
Shake(this);
}
private static void Shake(Form form)
{
var original = form.Location;
var rnd = new Random(1337);
const int shake_amplitude = 10;
for (int i = 0; i < 10; i++)
{
form.Location = new Point(original.X + rnd.Next(-shake_amplitude, shake_amplitude), original.Y + rnd.Next(-shake_amplitude, shake_amplitude));
System.Threading.Thread.Sleep(20);
}
form.Location = original;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With