0

所以我在用 C# 4.0 编写的 Winforms 应用程序中有一个自定义 Button 类。该按钮通常包含一个静态图像,但当发生刷新操作时,它会切换到动画 AJAX 样式按钮。为了使图像动画化,我设置了一个计时器,它在每个刻度上推进图像动画并将其设置为按钮图像。这是我让它工作的唯一方法。我的解决方案不是那么有效;任何意见将是有益的。

所以有两个问题: 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. 我认为您不应该每次都从资源中加载图像。更好的方法是预加载图像帧一个并保留参考。然后使用它在每个刻度上设置适当的帧。

正如我最近测试的那样,动画 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();
}

另一种选择是使用ImageList带有预加载静态帧的属性和循环属性,ImageIndex就像你在SelectActiveFrame上面做的那样。

于 2011-07-20T03:24:29.290 回答