Dan*_*lba 2 c# datagridview animated-gif winforms
我在 a 中包含了一个动画 gif DataGridView,但图像显示为静态。是否可以?
小智 5
我实现了一个 DataGridViewImageAnimator 类,负责处理任何 DataGridView 的 gif 图像动画。DataGridViewImageAnimator 的实例监视给定的 DataGridView 并对其中显示的任何 gif 图像进行动画处理。您可以从https://docs.google.com/open?id=0B1r6und31C6BQXktM2VQN1Jza2c下载源代码
您可以在包含 DataGridView 的表单中创建动画制作器,如下所示:
public partial class YourForm : Form
{
private DataGridViewImageAnimator dataGridImageAnimator;
public YourForm()
{
InitializeComponent();
dataGridImageAnimator = new DataGridViewImageAnimator(dataGridView1);
}
// ...
}
Run Code Online (Sandbox Code Playgroud)
或者,您可以使用已在其构造函数中执行此操作的 DataGridView 派生类,如下所示的 AnimatedDataGridView 类(代码可在https://docs.google.com/open?id=0B1r6und31C6BQnZUaTBjVXA4SkE获取)
using System.Windows.Forms;
namespace JLR.Utils
{
public class AnimatedDataGridView : DataGridView
{
private DataGridViewImageAnimator _imageAnimator;
public AnimatedDataGridView()
: base()
{
_imageAnimator = new DataGridViewImageAnimator(this);
}
}
}
Run Code Online (Sandbox Code Playgroud)
DataGridViewImageAnimator 的完整代码如下所示:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Windows.Forms;
namespace JLR.Utils
{
public class DataGridViewImageAnimator
{
private class RowCol
{
public int Column { get; set; }
public int Row { get; set; }
public RowCol(int column, int row)
{
Column = column;
Row = row;
}
public override bool Equals(object obj)
{
if (obj == null)
return false;
RowCol other = obj as RowCol;
if (other == null)
return false;
return (other.Column == Column && other.Row == Row);
}
public bool Equals(RowCol other)
{
if (other == null)
return false;
return (other.Column == Column && other.Row == Row);
}
public override int GetHashCode()
{
return Column.GetHashCode() ^ Row.GetHashCode();
}
public static bool operator ==(RowCol a, RowCol b)
{
// If both are null, or both are same instance, return true.
if (object.ReferenceEquals(a, b))
{
return true;
}
// If one is null, but not both, return false.
if (((object)a == null) || ((object)b == null))
{
return false;
}
// Return true if the fields match:
return a.Column == b.Column && a.Row == b.Row;
}
public static bool operator !=(RowCol a, RowCol b)
{
return !(a == b);
}
}
private class AnimatedImage
{
private DataGridView DataGridView { get; set; }
private HashSet<RowCol> _cells = new HashSet<RowCol>();
public Image Image { get; set; }
public AnimatedImage(Image image, DataGridView dataGridView)
{
Image = image;
DataGridView = dataGridView;
}
public bool IsUsed { get { return _cells.Count > 0; } }
public void AddCell(RowCol rowCol)
{
Debug.Assert(!_cells.Contains(rowCol));
if (!_cells.Contains(rowCol))
{
_cells.Add(rowCol);
if (_cells.Count == 1)
{
// this is the first cell we are using this image, so start animation
ImageAnimator.Animate(Image, new EventHandler(OnFrameChanged));
}
}
}
public void RemoveCell(RowCol rowCol)
{
Debug.Assert(_cells.Contains(rowCol));
if (_cells.Contains(rowCol))
{
_cells.Remove(rowCol);
if (_cells.Count == 0)
{
// this was the last cell we were using this image, so stop animation
ImageAnimator.StopAnimate(Image, new EventHandler(OnFrameChanged));
}
}
}
private void OnFrameChanged(object o, EventArgs e)
{
// invalidate each cell in which it's being used
RowCol[] rcs = new RowCol[_cells.Count];
_cells.CopyTo(rcs);
foreach (RowCol rc in rcs)
{
DataGridView.InvalidateCell(rc.Column, rc.Row);
}
}
}
private Dictionary<RowCol, Image> _values = new Dictionary<RowCol, Image>();
private Dictionary<Image, AnimatedImage> _animatedImages = new Dictionary<Image, AnimatedImage>();
private DataGridView _dataGridView;
public DataGridViewImageAnimator(DataGridView dataGridView)
{
_dataGridView = dataGridView;
_dataGridView.CellPainting += new DataGridViewCellPaintingEventHandler(OnDatagridCellPainting);
}
void OnDatagridCellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
if (e.ColumnIndex >= 0 && e.RowIndex >= 0)
{
object value = _dataGridView[e.ColumnIndex, e.RowIndex].Value;
CheckValue(e.ColumnIndex, e.RowIndex, value);
ImageAnimator.UpdateFrames();
}
}
private void AddImage(RowCol rowCol, Image image)
{
_values[rowCol] = image;
AnimatedImage animatedImage;
if (!_animatedImages.TryGetValue(image, out animatedImage))
{
animatedImage = new AnimatedImage(image, _dataGridView);
_animatedImages[image] = animatedImage;
}
animatedImage.AddCell(rowCol);
}
private void RemoveImage(RowCol rowCol, Image image)
{
Debug.Assert(_values.ContainsKey(rowCol));
Debug.Assert(_animatedImages.ContainsKey(image));
_values.Remove(rowCol);
AnimatedImage animatedImage;
if (_animatedImages.TryGetValue(image, out animatedImage))
{
animatedImage.RemoveCell(rowCol);
if (!animatedImage.IsUsed)
{
_animatedImages.Remove(image);
}
}
}
private void CheckValue(int columnIndex, int rowIndex, object value)
{
RowCol rowCol = new RowCol(columnIndex, rowIndex);
// is the new value an Image, and can it be animated?
Image newImage = value as Image;
bool newValueIsImage = (newImage != null && ImageAnimator.CanAnimate(newImage));
// is there a previous image value?
Image oldImage;
if (_values.TryGetValue(rowCol, out oldImage))
{
if (newImage == oldImage)
{
// same old image --> nothing else to do
return;
}
RemoveImage(rowCol, oldImage);
}
if (newValueIsImage)
{
AddImage(rowCol, newImage);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
问候,
| 归档时间: |
|
| 查看次数: |
8454 次 |
| 最近记录: |