9

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

MainForm Code

 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

ShakeForm Code

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
4

4 回答 4

16

你有没有尝试过这样的事情?

    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;
    }
于 2013-05-22T11:47:46.387 回答
15

典型的问题是表单上的控件太多,导致绘制速度太慢。所以只是假装它,创建一个显示表单位图的无边框窗口并摇动那个。使用表单的 DrawToBitmap() 方法创建位图。使用 32bppPArgb 作为像素格式,它的绘制速度是其他所有格式的十倍。

于 2013-05-22T11:38:57.687 回答
1

您可以使用 Windows 7 的 Aero Shake 功能来实现此目的。

更好的是,您可以查看以下链接以获取更多详细信息:

http://www.codeproject.com/Articles/36294/Aero-Shake

于 2013-05-22T10:52:29.897 回答
0

这是一个小解决方法,您可以尝试一下。

private void button1_Click(object sender, EventArgs e)
    {
        this.Width = this.Width - 10;
        this.Height = this.Height - 10;
        Thread.Sleep(15);
        this.Width = this.Width + 10;
        this.Height = this.Height + 10;
    }
于 2013-05-22T10:58:07.347 回答