3

.NETプログラミングを学ぼうとしています。学習の一環として、ボタンにいくつかの効果を加えようとしました。それは機能しています...しかし、私が想像したほどスムーズではありません! これを行うより良い方法はありますか?前もって感謝します!

私の必要性:

3つのボタンがあります。いずれかの上にマウスを置くと拡大し、そのボタンからマウスを離すと元のサイズに戻ります。

private void button1_MouseHover(object sender, EventArgs e)
    {
        button1.BackColor = Color.White;
        button1.Width = 130;
        button1.BringToFront();            
    }

    private void button1_MouseLeave(object sender, EventArgs e)
    {
        button1.BackColor = Color.Red;
        button1.Width = 75;         
    }

    private void button2_MouseHover(object sender, EventArgs e)
    {
        button2.BackColor = Color.Gray;
        button2.Width = 130;
        button2.BringToFront();            
    }

    private void Form1_MouseLeave(object sender, EventArgs e)
    {
        button2.BackColor = Color.Red;
        button2.Width = 75;

    }

    private void button3_MouseHover(object sender, EventArgs e)
    {
        button3.BackColor = Color.DimGray;
        button3.Width = 130;
        button3.BringToFront();
    }

    private void button3_MouseLeave(object sender, EventArgs e)
    {
        button3.BackColor = Color.Red;
        button3.Width = 75;

    }
4

3 に答える 3

6

最初に、まったく同じことを 3 回やりたくありません。ボタンに適切なハンドラーを追加する単一のメソッドを作成し、任意のボタンを処理するコードを 1 回記述するだけです。

拡張/縮小ティック ハンドラーに移動し、percentComplete値を使用して高さを設定したり、スペクトルに沿って色を移動したり (これには、色の数学が必要になります)、またはボタン。それを一般化することに本当に動機がある場合は、指定された進捗率に基づいてオブジェクトに何かを行うパラメーターを のメソッドに追加できますAction<double>

public void AddAnimation(Button button)
{
    var expandTimer = new System.Windows.Forms.Timer();
    var contractTimer = new System.Windows.Forms.Timer();

    expandTimer.Interval = 10;//can adjust to determine the refresh rate
    contractTimer.Interval = 10;

    DateTime animationStarted = DateTime.Now;

    //TODO update as appropriate or make it a parameter
    TimeSpan animationDuration = TimeSpan.FromMilliseconds(250);
    int initialWidth = 75;
    int endWidth = 130;

    button.MouseHover += (_, args) =>
    {
        contractTimer.Stop();
        expandTimer.Start();
        animationStarted = DateTime.Now;
        button.BackColor = Color.DimGray;
    };

    button.MouseLeave += (_, args) =>
    {
        expandTimer.Stop();
        contractTimer.Start();
        animationStarted = DateTime.Now;
        button.BackColor = Color.Red;
    };

    expandTimer.Tick += (_, args) =>
    {
        double percentComplete = (DateTime.Now - animationStarted).Ticks
            / (double)animationDuration.Ticks;

        if (percentComplete >= 1)
        {
            expandTimer.Stop();
        }
        else
        {
            button.Width = (int)(initialWidth +
                (endWidth - initialWidth) * percentComplete);
        }
    };

    contractTimer.Tick += (_, args) =>
    {
        double percentComplete = (DateTime.Now - animationStarted).Ticks
            / (double)animationDuration.Ticks;

        if (percentComplete >= 1)
        {
            contractTimer.Stop();
        }
        else
        {
            button.Width = (int)(endWidth -
                (endWidth - initialWidth) * percentComplete);
        }
    };
}
于 2013-01-16T19:08:16.560 に答える
4

WinFormsを使用している場合、アニメーションはかなり面倒になり、Timerオブジェクトを介して自分で処理する必要があります。

.NET に慣れていて、アニメーションとスタイリングを備えた見栄えの良いアプリケーションを作成したい場合は、代わりにWPFを検討することを強くお勧めします。C#またはXAMLを使用して非常に簡単にアニメーションを実行できます。

WinForms ではまだ可能ですが、これらの機能が既に WPF に組み込まれている (そして最適化されている) ため、はるかに多くの開発時間がかかります。

于 2013-01-16T19:12:50.093 に答える
0

When you modify a controls properties, it takes effect instantaneously. What you desire is something that is usually known as some type of fade or tweening. There might be libraries out there to do this, but if you wanted to write this yourself for fun, you can use a Timer object, and on each tick update the color.

What you would do is set a color as the TargetColor somewhere(this is a variable or property you make up), and then start a timer that ticks maybe every 10 milliseconds. In each tick, you look at the start time, and how long has passed since then. If you want the animation to take place of a full second, then that is 1000 milliseconds. So during each tick, you look at the amount of time that has passed, maybe 200 milliseconds, then divide 200/1000 to get the fraction of time that you have gone into the animation. Then you look at a difference between the Start and Target Color, multiply that difference by the fraction, and add the result to the start color. In other words, 200 milliseconds into an animation that last 1000 milliseconds, means you are 20% into the animation. Thus you want to set the color to be whatever color is 20% from the start color towards the end color.

There's alot you could do to refine this. Perhaps having a subclass Button control that encapsulates the timer and exposes functions/properties to track start/end color, animation transition time, etc. Most animated UI features like this let you specify how long the animation should last, and then it interpolates the inbetween states as it transitions. This is the origin of the term tweening, as it comes from transitioning from one state to another by inbetweening

于 2013-01-16T19:09:38.430 に答える