0

そのため、C#4.0で記述されたWinformsアプリにカスタムButtonクラスがあります。ボタンは通常は静止画像を保持しますが、更新操作が行われると、アニメーション化されたAJAXスタイルのボタンに切り替わります。画像をアニメーション化するために、目盛りごとに画像アニメーションを進め、それをボタン画像として設定するタイマーを設定しています。それが私がそれを機能させることができる唯一の方法です。私が持っている解決策はそれほど効率的ではありません。どんなアドバイスも役に立ちます。

したがって、2つの質問があります。1。使用する必要のある機能を見落としているような、より簡単な方法はありますか?2.画像​​を手動でアニメーション化するためのより良い方法はありますか?

私が各ティックで行っていることの以下のコードを見つけてください。改善の最初の領域:画像の各フレームをリストにコピーしますか?_image.Dispose();に注意してください。ローカルイメージの破棄に失敗すると、メモリリークが発生していました。

ここでアドバイスをありがとう。効率的な解決策ができたら、オンラインで何かを投稿してリンクします。

    private void TickImage()
    {
        if (!_stop)
        {
            _ticks++;

            this.SuspendLayout();

            Image = null;

            if(_image != null)
                _image.Dispose();

            //Get the animated image from resources and the info
            //required to grab a frame
            _image = Resources.Progress16;
            var dimension = new FrameDimension(_image.FrameDimensionsList[0]);
            int frameCount = _image.GetFrameCount(dimension);

            //Reset to zero if we're at the end of the image frames
            if (_activeFrame >= frameCount)
            {
                _activeFrame = 0;
            }

            //Select the frame of the animated image we want to show
            _image.SelectActiveFrame(dimension, _activeFrame);

            //Assign our frame to the Image property of the button
            Image = _image;

            this.ResumeLayout();

            _activeFrame++;

            _ticks--;
        }
    }
4

1 に答える 1

2
  1. Winformsは、それ自体ではアニメーション機能にそれほど到達していないと思います。より高度なアニメーションの使用が必要な場合は、サードパーティのソリューションを検討してください。
  2. ティックごとにリソースから画像をロードするべきではないと思います。より良い方法は、画像フレームを1つプリロードし、参照を保持することです。次に、それを使用して、ティックごとに適切なフレームを設定します。

私が最近テストしたように、アニメーションGIFは、少なくとも標準のボタンでは、追加のコーディングなしでうまくアニメーション化されています。ただし、フレームを手動で修正する必要がある場合は、次のようにしてみてください。

// put this somewhere in initialization
private void Init() 
{
    Image image = Resources.Progress16;
    _dimension = new FrameDimension(image.FrameDimensionsList[0]);
    _frameCount = image.GetFrameCount(_dimension);
    image.SelectActiveFrame(_dimension, _activeFrame);
    Image = image;
}

private void TickImage()
{
    if (_stop) return;
    // get next frame index
    if (++_activeFrame >= _frameCount)
    {
        _activeFrame = 0;
    }
    // switch image frame
    Image.SelectActiveFrame(_dimension, _activeFrame);
    // force refresh (NOTE: check if it's really needed)
    Invalidate();
}

もう1つのオプションはImageList、プリロードされた静的フレームでプロパティを使用し、上記のImageIndex場合と同じように適切にサイクルすることですSelectActiveFrame

于 2011-07-20T03:24:29.290 に答える