Achieve Slide Show Effects in Windows Forms Easily with the WebBrowser Control

I love the new managed WebBrowser control. It makes it so easy to hack any number of fantastic things into Windows Forms.

Let's say you want to do a slide show between various images. You can muck around with DirectX...or you can just use the transitions and filters built into the WebBrowser control and the DHTML Document Object Model. The following Visual Basic.NET code shows a UserControl created in Visual Studio 2005 that uses the WebBrowser control's built-in transitions and filters to pull this off. Since IE defines a large number of transitions and filters, you can do any number of effects: fade, random dissolve, window blinds, etc. (See Introduction to Filters and Transitions to behold all of the possibilities.)

To recreate this yourself, create a UserControl called Slideshow. Add a WebBrowser control named webBrowser1, and set the Dock property to Fill. Paste in the following code to Slideshow.vb, and you're good to go. To use the control in your application, set the ImageFilePath property to the directory containing your images, and call StartSlideshow() to start it up.

Imports System.IO

Public Class Slideshow
Private _ImageFolderPath As String
Private CurrentImage As Integer = 0
Private Files As String()
Private _Loop As Boolean = True

    Private _AllowedExtensions As Dictionary(Of String, Integer)

    Public Property ImagePath() As String
Get
ImagePath = _ImageFolderPath
End Get

        Set(ByVal value As String)
Dim FileStrs As String() = Nothing

            ' If we don't include the Is Nothing test, the designer sets the value to Nothing automagically,
' causing our form to fail to load at design time.
If (Directory.Exists(value) Or value Is Nothing) Then
_ImageFolderPath = value
Else
Throw New System.IO.FileNotFoundException("Directory does not exist.")
End If
End Set
End Property

    Public Sub StartSlideshow(ByVal milliSeconds As Integer, ByVal LoopSlideshow As Boolean)
If (_ImageFolderPath Is Nothing) Then
Throw New ArgumentException("You must set a valid value for ImagePath first.")
End If

        ' Load up the array of images through which to cycle.
Dim FilesTmp As String() = Directory.GetFiles(Me._ImageFolderPath)
Dim TmpArray As List(Of String) = New List(Of String)()
' Remove elements that aren't images.
For Each File As String In FilesTmp
Dim Ext As String = File.Substring(File.LastIndexOf(".") + 1).ToLower()
If (Me._AllowedExtensions.ContainsKey(Ext)) Then
TmpArray.Add(File)
End If
Next

        Files = TmpArray.ToArray()

        _Loop = LoopSlideshow

        ' Load up the initial page. We will manipulate the page by making Javascript calls via HtmlDocument's
' InvokeScript() method.
Dim NewPage As String = "<HTML>" & vbCr & _
"<script type=""text/javascript"">" & vbCr & _
"function transitionImage(newImg){" & vbCr & _
"var imgObject = document.getElementById(""ourImage"");" & vbCr & _
"imgObject.filters[0].apply();" & vbCr & _
"imgObject.src = newImg;" & vbCr & _
"imgObject.filters[0].play();" & vbCr & _
"}</script>" & vbCr & _
"<BODY><IMG src=""" & GetNextImage() & _
""" id=""ourImage"" style=""position:absolute;top:0px;left:0px;
filter:progid:DXImageTransform.Microsoft.RandomDissolve(Duration=2);" & _
"width:" & WebBrowser1.Width & ";height:" & WebBrowser1.Height & ";""></BODY></HTML>"
WebBrowser1.DocumentText = NewPage

        ' Start the timer.
Me.ImageSlideTimer.Interval = milliSeconds
Me.ImageSlideTimer.Start()
End Sub

    Public Sub StopSlideshow()
Me.ImageSlideTimer.Stop()
End Sub

    Private Function GetNextImage() As String
Dim UriStr As String = Nothing

        If (CurrentImage = Files.Length) Then
If (_Loop) Then
CurrentImage = 0
Else
' That was it - time to bail.
StopSlideshow()
End If
End If

        UriStr = Files(CurrentImage)
CurrentImage += 1

        GetNextImage = UriStr
End Function

    Private Sub ImageSlideTimer_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ImageSlideTimer.Tick
Dim UriStr As String = GetNextImage()

        ' Create transition page for image.
Dim args(1) As String
args(0) = UriStr
WebBrowser1.Document.InvokeScript("transitionImage", args)
End Sub

    Private Sub Slideshow_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Me._AllowedExtensions = New Dictionary(Of String, Integer)()
With Me._AllowedExtensions
.Add("jpg", 1)
.Add("jpeg", 1)
.Add("gif", 1)
.Add("png", 1)
.Add("tif", 1)
.Add("tiff", 1)
End With
End Sub
End Class