Animate Images in DataGridView

后端 未结 1 629
孤街浪徒
孤街浪徒 2021-01-27 07:28

I wrote the helper class below in order to animate images in a DataGridView, which is not working (images aren\'t animated).

Before that, I found some sampl

1条回答
  •  梦毁少年i
    2021-01-27 07:36

    A custom Column with custom Cells offers some advantages.

    All the design logic is confined in one place and it can be selected as a Column template at design time using the DataGridView designer.


    The performace is quite good (tested with 200 animated cells) and I didn't notice any flickering.

    The animated Gifs can be Stretched or Zoomed as usual, using the designer settings, by code or manually resizing the Rows/Columns.

    However, I can't consider it complete, because I couldn't find out a good way to start all the animations using this custom Column class methods or properties.

    EDIT:
    Added an Extension method to the DataGridView (DataGridView.Animate()).
    This allows to hide the invalidating procedure.
    After the DataGridView Data Binding is complete, simply call the extension method:

    DataGridView1.DataSource = [DataSource]
    DataGridView1.Animate()
    

    The Module containing the Extension method:

    Imports System.Runtime.CompilerServices
    
    Module DGVExtesions
    
        
        Public Sub Animate(ByVal AnimatedGrid As DataGridView)
            Try
                For Each row As DataGridViewRow In AnimatedGrid.Rows
                    For Each cell As DataGridViewCell In row.Cells.OfType(Of AnimatedDGVColumn.AnimatedCell)()
                        AnimatedGrid.InvalidateCell(cell)
                    Next
                Next
            Catch ex As Exception
                Trace.WriteLine("Exception: {0}", ex.Message)
            End Try
    
        End Sub
    
    End Module
    

    Of course this is still not good enough. Some more research is needed.

    This is the custom Animated Column class:

    Imports System.ComponentModel
    Imports System.Windows.Forms
    
    Public Class AnimatedDGVColumn
        Inherits System.Windows.Forms.DataGridViewColumn
    
        Private custCellTemplate As AnimatedCell
    
        Public Sub New()
            Me.custCellTemplate = New AnimatedCell
            Me.custCellTemplate.ImageLayout = DataGridViewImageCellLayout.Zoom
            MyBase.CellTemplate = custCellTemplate
            Me.AutoSizeMode = DataGridViewAutoSizeColumnMode.None
            Me.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter
        End Sub
    
         _
        
        Public Property ImageLayout As DataGridViewImageCellLayout
            Get
                Return Me.custCellTemplate.ImageLayout
            End Get
            Set(ByVal value As DataGridViewImageCellLayout)
                Me.custCellTemplate.ImageLayout = value
            End Set
        End Property
    
        Public Overloads Property CellTemplate As AnimatedCell
            Get
                Return Me.custCellTemplate
            End Get
            Set(value As AnimatedCell)
                Me.custCellTemplate = value
                MyBase.CellTemplate = value
            End Set
        End Property
    
        Public Class AnimatedCell
            Inherits System.Windows.Forms.DataGridViewImageCell
    
            Private Animation As Image
            Private IsAnimating As Boolean
    
            Public Sub New()
                Me.Animation = Nothing
                Me.IsAnimating = False
            End Sub
    
            Public Overloads Property ImageLayout() As DataGridViewImageCellLayout
                Get
                    Return MyBase.ImageLayout
                End Get
                Set(ByVal value As DataGridViewImageCellLayout)
                    MyBase.ImageLayout = value
                End Set
            End Property
    
            Protected Overrides Sub Paint(graphics As Graphics, clipBounds As Rectangle, cellBounds As Rectangle, rowIndex As Integer, elementState As DataGridViewElementStates, value As Object, formattedValue As Object, errorText As String, cellStyle As DataGridViewCellStyle, advancedBorderStyle As DataGridViewAdvancedBorderStyle, paintParts As DataGridViewPaintParts)
                If (IsDBNull(value)) OrElse (value Is Nothing) Then Return
                If Me.Animation Is Nothing Then
                    Me.Animation = CType(formattedValue, Image)
                End If
                Animate()
                ImageAnimator.UpdateFrames()
    
                MyBase.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState, Nothing, Me.Animation, errorText, cellStyle, advancedBorderStyle, paintParts)
            End Sub
    
            Private Sub Animate()
                If Me.IsAnimating = True Then Return
                If (Me.Animation IsNot Nothing) AndAlso ImageAnimator.CanAnimate(Me.Animation) = True Then
                    ImageAnimator.Animate(Me.Animation, AddressOf Me.RotateFrame)
                    Me.IsAnimating = True
                End If
            End Sub
    
            Private Sub RotateFrame(o As Object, e As EventArgs)
                If Me.RowIndex > -1 Then
                    Me.DataGridView.InvalidateCell(Me)
                End If
            End Sub
    
            Public Overrides Function Clone() As Object
                Dim result As AnimatedCell = New AnimatedCell With {
                            .IsAnimating = False,
                            .Animation = Nothing,
                            .ImageLayout = Me.ImageLayout
                            }
                Return result
            End Function
    
        End Class
    
    End Class
    

    0 讨论(0)
提交回复
热议问题