开发者

Switching between animated image and static image in winforms button

So I have a custom Button class in a Winforms app written in C# 4.0. The button holds a static image normally, but when a refresh operation takes place it switches to an animated AJAX-style button. In order to animate the image I have a timer set up that advances the image animation on every tick and sets that as the button image. That's the only way I can get it to work. The solution I have isn't that efficient; any advice would be helpful.

So two questions: 1. Is there an easier way - as in am I overlooking some feature I should be using? 2. Is there a better way to manually animate the image?

Find code below of what I'm doing on each tick. The first area of improvement: maybe copy each frame of the image to a list? Note the _image.Dispose(); failing to dispose of a local Image was causing memory leaks.

Thanks for any advice here. I will post something online and link it 开发者_高级运维once I have an efficient solution.

    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--;
        }
    }


  1. I guess Winforms is not so reach in animation capabilities on its own. If you want more advanced animation use may consider some third-party solutions.
  2. I think you should not load image from resource every tick. The better way is to preload image frames one and hold the reference. Then use it to set appropriate frame every tick.

As I've recently tested, animated gifs are animating well without any additional coding, at least on standard buttons. But if you still need to aminate frames manually, you may try something like this:

// 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();
}

Another option is to use ImageList property with preloaded static frames and cycle ImageIndex propery just as you do it with SelectActiveFrame above.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜