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
            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
                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
            End If

        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
    End Sub

    Public Sub StopSlideshow()
    End Sub

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

        If (CurrentImage = Files.Length) Then
            If (_Loop) Then
                CurrentImage = 0
                ' That was it - time to bail.
            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

Comments (6)
  1. Jeremy Holt says:

    Please excuse me for this unrelated question, but I do hope you can help…..

    I’m using the WebBrowser (Form 2.0) control on a form as a help file. The html file is saved as a resource in the assembly.

    I have no problem opening the htm with      Me.WebBrowser1.DocumentText = My.Resources.WhatsNew

    However, I’m going nuts trying to work out how to reference any images referenced in the htm document itself.

    Let say I save the image file in the same directory as the htm. The htm file refers to the image as  <img src=".MyImage.gif" />.

    I’ve tried embedding the image as a resource, Build Action: Content etc. but this doesn’t work. When I run the application, the WebBrowser shows the missing image symbol with a reference to "about:blank.MyImage.gif".

    Any thoughts would be greatly appreciated.

    Many thanks

    Jeremy Holt

  2. WinFormsUE says:

    Hey dude – contact me via email and we can chat. You *may* be able to use the res protocol:

    If that doesn’t work, you’ll need to use absolute URLs pointing either to a location on the file system or to images on a server.

  3. Dynamically Detecting the Data Directory

    My Slideshow control (which I discussed in a previous post)…

Comments are closed.

Skip to main content