我编写了下面的helper类,以便在DataGridView
中动画化图像,但它不起作用(图像没有动画化)。
在此之前,我在wen上找到了一些示例代码,但它们也不起作用。
我想了解这是如何工作的,而不是仅仅因为我的应用程序能工作就把一段代码塞进去。为什么我的代码不能做它预期的事情?
编辑
我发现了它不工作的原因。源代码DataTable
本身不包含图像:它们通过CellFormatting
处理方法分配给DataGridView
的Cells。由于该事件也一直触发,因此总是传递一个新鲜的图像对象,因此它总是显示图像的第一帧。当我创建一个新列并将原生图像值存储在其中时,它们按照需要进行动画处理。
现在的问题是是否可以在DataGridView
的CellFormatting
事件处理程序方法中为分配给.FormattedValue
属性的图像设置动画?
Public Class DataGridViewImageAnimator
Private WithEvents MyDataGridView As DataGridView
Public Sub New(dataGridView As DataGridView)
MyDataGridView = dataGridView
End Sub
Private MyAnimatedImages As New Dictionary(Of Point, Image)
Private Sub ImageAnimator_FrameChanged(sender As Object, e As EventArgs)
Dim imageCells = MyDataGridView.Rows.Cast(Of DataGridViewRow).SelectMany(
Function(dgvr) dgvr.Cells.OfType(Of DataGridViewImageCell))
For Each cell In imageCells
Dim img = TryCast(cell.FormattedValue, Image)
If img IsNot Nothing AndAlso MyAnimatedImages.ContainsValue(img) Then
MyDataGridView.InvalidateCell(cell)
End If
Next
End Sub
Private Sub MyDataGridView_CellPainting(
sender As Object,
e As DataGridViewCellPaintingEventArgs
) Handles MyDataGridView.CellPainting
If e.ColumnIndex >= 0 AndAlso e.RowIndex >= 0 Then
Dim cell = MyDataGridView(e.ColumnIndex, e.RowIndex)
Dim drawPoint = MyDataGridView.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, True).Location
Dim pt = New Point(e.ColumnIndex, e.RowIndex)
Dim cellImg = TryCast(cell.FormattedValue, Image)
If MyAnimatedImages.ContainsKey(pt) AndAlso Equals(MyAnimatedImages(pt), cellImg) Then
'If image is already registered as animated, and is still in cell
ImageAnimator.UpdateFrames()
e.Graphics.DrawImage(cellImg, drawPoint)
Else
If MyAnimatedImages.ContainsKey(pt) Then
'If image registered as animated is no longer in cell
ImageAnimator.StopAnimate(MyAnimatedImages(pt), AddressOf ImageAnimator_FrameChanged)
MyAnimatedImages.Remove(pt)
End If
If cellImg IsNot Nothing AndAlso ImageAnimator.CanAnimate(cellImg) Then
'If cell contains an image not yet registered as animated
MyAnimatedImages(pt) = cellImg
ImageAnimator.Animate(MyAnimatedImages(pt), AddressOf ImageAnimator_FrameChanged)
ImageAnimator.UpdateFrames()
e.Graphics.DrawImage(cellImg, drawPoint)
End If
End If
End If
End Sub
End Class
1条答案
按热度按时间qlckcl4x1#
带有自定义单元格的自定义列具有一些优点。
所有的设计逻辑都被限制在一个地方,可以在设计时使用
DataGridView
设计器将其选作Column模板。性能是相当不错的(测试了200个动画细胞),我没有注意到任何 Flink 。
可以使用设计器设置、通过代码或手动调整行/列的大小,像往常一样拉伸或缩放动画Gif。
然而,我不能认为它是完整的,因为我找不到一个好的方法来启动所有的动画使用这个自定义的列类的方法或属性。
编辑:
已将扩展方法添加到
DataGridView
(DataGridView.Animate()
)。这允许 * 隐藏 * 无效过程。
DataGridView
数据绑定完成后,只需调用扩展方法:包含Extension方法的模块:
当然,这还不够好,还需要更多的研究。
这是自定义动画列类: