 | Wednesday, July 25, 2007 |
| Creating a Filmstrip Style User Control in VB.2005 |
| By James Acosta |
| |
|
If you've ever switched to Filmstrip view in Windows Explorer (XP and Vista)
or used a product similar to Adobe Bridge that displays thumbnails of the
pictures in a folder horizontally at the bottom while displaying a scaled
version above, then you've seen a filmstrip control.
If
you're developing an application that displays pictures, a filmstrip control
might come in very handy; too bad Visual Studio 2005 doesn't come with one.
Fortunately, its fairly simple to create one on your own similar to the example
project pictured to the left (available in the download at the bottom of the
article). Although the individual components and coding could all be
included on whichever form you're opting to have the filmstrip on, creating a
user control simplifies this and enables you to reuse in other projects.
Start by opening Visual Studio 2005 (VS) and creating a new Windows Control
Library project, named FilmstripControl. Rename
UserControl1.vb to Filmstrip.vb.
A simple filmstrip consists of little more than a control that displays
thumbnails of one or more images, a label below each image (optional, but
handy), the ability to scroll horizontally when there are more images than
available space, and a mechanism by which your program is alerted with the name
of the thumbnail clicked. Approaching this from the "easy
direction", thumbnails are easily displayed using the PictureBox control and
labels with the Label control. Our new user control provides us with a
blank working environment, but that environment may not be the best starting
place. As our filmstrip will essentially be grouping PictureBox and Label
controls together, we should look at starting with one of the VS existing
Container controls, such as the Panel control. The filmstrip control needs
the ability to hold more thumbnails than the user's display might make visible
at one time, which means we need to have the ability to scroll as needed.
We could use the blank user control environment and a VScrollBar control hidden
when not needed, but that is a lot of extra coding that the Panel control
already takes care of for us.
To build on the existing Panel control, switch the Solution Explorer's view
from the default view to the "Show All Files" view, using the toolbar button.
Once this view is enabled, additional files under the
Filmstrip.vb control will be come visible. Double-click
Filmstrip.Designer.vb. In order to work with an
existing control, we need to change where our new control inherits from.
At the top of the designer file, you will see a statement that reads
Inherits System.Windows.Forms.UserControl.
Change UserControl to Panel.
Before you close the file, you will notice that towards the bottom of the class
definition, VS has indicated that Me.AutoScaleMode is
now in error. Because this is part of the UserControl
environment and not the Panel environment, you can delete this section.
Remove the InitializeComponent subroutine including
the <System...> _ line and the commented notes above
it. Switch back to the Filmstrip.vb file.
If you went into the GUI design view, you will no longer see the blank
environment, but rather a notice about switching to code view. Switch to
the code view.
To facilitate adding images to the filmstrip, we need the control to expose a
method (subroutine) to the designer that takes the name of the image file to
add. Next, because our control has no static images, we need to create a
new PictureBox control, size it appropriately for a thumbnail, and load / size
the image. Because we also want to display the name of the
image below the thumbnail, we need to also create a new label control with the
text property properly set.
Public Sub AddPicture(ByVal strFileName
As String)
Dim objFileInfo
As System.IO.FileInfo objFileInfo = _
My.Computer.FileSystem.GetFileInfo(strFileName)
Dim NewPictureBox
As New PictureBox
NewPictureBox.Image = Image.FromFile(strFileName)
NewPictureBox.Size = New
Size(100, 100)
NewPictureBox.SizeMode = PictureBoxSizeMode.Zoom
NewPictureBox.Tag = strFileName
Dim NewLabel
As New Label
NewLabel.Text = objFileInfo.Name
NewLabel.AutoEllipsis = True
NewLabel.AutoSize = False
NewLabel.TextAlign = ContentAlignment.MiddleCenter
End Sub
We've made a few assumptions with our thumbnail in this code. First,
the size of the thumbnail is a maximum of 100 by 100 pixels, and to resize the
picture the PictureBox control is set to zoom. Although this is fine for
our demo, a better control would resize the thumbnails as appropriate for the size
of the control, and to conserve the amount of memory used, the PictureBox
control would actually generate a thumbnail image instead of dynamically
shrinking the full image down to fit the size of the control. The download
contains a second take on our final results that includes both these actions.
The name of the original file is also stored in the Tag
property so we can identify it later.
The next step is to add the new controls to the Panel control and position
them properly. In order to put them in the right spot, we need know where
in the control they should be placed. The horizontal position remains
constant, a simple line-up of all the PictureBox controls. The vertical position is
derived by keeping track of the widths of all previously placed PictureBoxes
plus the widths of all padding in-between and setting the
Left property to this position. This is accomplished by
creating an integer variable to keep track of the offset distance. This
should be a class-level variable instead of a subroutine-level static variable
as other routines will need to access the variables value.
Once our new PictureBox is added to the Panel and positioned, our new label is then added and placed directly
below:
Public Class Filmstrip
Private Offset
as Integer = 5
and
NewLabel.TextAlign =
ContentAlignment.MiddleCenter
NewPictureBox.Location = New Point(Offset, 5)
Me.Controls.Add(NewPictureBox)
NewLabel.Location = New Point(Offset,
_
5 + NewPictureBox.Height)
Me.Controls.Add(NewLabel)
Offset += NewPictureBox.Width +
5
End Sub
Because we have set the size of the thumbnail to a 100 pixel square and a label below, we need to set a minimum size for the control when
placed so as to correctly display the informtion. We also need to take into consideration
that when the width of the added thumbnails exceed the visible width of the
Panel control, scroll bars will appear. This is OK for horizontal
scrolling, but vertical is not expected so we need to add additional height. Because there is no physical
control we have to set default values programmatically in the controls New
event:
Public Sub New()
Me.AutoScroll =
True
Me.MinimumSize =
New Size(300, 150)
End Sub
We should also add a way to remove all the thumbnails. This is a very
straightforward process - just delete all controls contained within the Panel,
reset the new PictureBox location offset, then reset the scrollbars (they won't go away by themselves when you
programmatically delete the contents):
Public Sub Clear()
While Me.Controls.Count > 0
Me.Controls.Remove(Me.Controls.Item(0))
End While
Offset = 5
Me.AutoScroll = True
End Sub
Our last task is to provide the developer notice when a user selects a
thumbnail. This is a little more complicated than adding a simple method
or code to an intrinsic event. In order to provide this information we
need to create a custom event. Start by adding the general event
definition to the class:
Public Class Filmstrip
Public Event OnImageClicked(
_
ByVal
sender As System.Object,
ByVal e As
EventArgs)
With the event defined, we need to create the routine that will generate the
data we will pass to the developer when the user performs the mouse click action
(at this point we haven't defined what action triggers our event).
Private Sub Image_Click( _
ByVal sender
As Object, ByVal e
As EventArgs)
Dim pb
As
PictureBox = CType(sender, PictureBox)
RaiseEvent OnImageClicked(pb.Tag.ToString,
e)
End Sub
This routine doesn't look like much. As is, the subroutine provides
us with the sending object (the dynamically created PictureBox). The
Tag property contains the path to the displayed file,
so all that is needed is to extract the data and pass it as an argument for the
event, which we raise (the definition for our custom event uses the
sender parameter as a
System.Object; anything, including a string, can be passed as a
System.Object.)
With our defined event linked to a routine that generates the data, our last
act is to link the generation routine to the click action of our dynamically
created PictureBox. To do this we need to add a command to our AddPicture
routine:
NewPictureBox.Tag = strFileName
AddHandler NewPictureBox.Click,
AddressOf Image_Click
Dim NewLabel As New Label
This is all we need to complete the simple
user control. The next step is to test it out. Add a new standard
Windows application project to our current project. Make sure you
save the entire solution, as our custom control will not become available to you
until the first save/build. Once saved and built, switch over to the Form1
in the new project and you will see the Filmstrip control at the top of the
toolbox.
Drag the Filmstrip control and two buttons to the form. You will notice
that the Filmstrip control defaults to the size we set. Switch to the code
view and add the following to the Form1 class:
Private Sub Button1_Click( _
ByVal sender
As System.Object, _
ByVal e
As System.EventArgs) _
Handles Button1.Click
Me.Filmstrip1.AddPicture("C:\Windows\Blue Lace 16.bmp")
End Sub
Private Sub Button2_Click( _
ByVal sender
As System.Object, _
ByVal e
As System.EventArgs) _
Handles Button2.Click
Me.Filmstrip1.Clear()
End Sub
Private Sub Filmstrip1_OnImageClicked( _
ByVal sender
As Object, _
ByVal e
As System.EventArgs) _
Handles Filmstrip1.OnImageClicked
MsgBox(sender.ToString)
End Sub
The code is relatively straightforward and needs very little explanation.
The program will add the same image over and over as we don't have a
user-selection dialog coded in, so you need to change it to an image you desire.
Before we test it, we need to set the added project to the start up project by
right-clicking the new project in the Solution Explorer window and selecting
"Set as StartUp Project".
Build the solution and try out the buttons. In very little coding
you've created a simple filmstrip. The download contains both the
completed demo project, as well as a second take on the filmstrip that expands
on the concept to include dynamic resizing of the control and better memory
management of images.
 |
Download the content mentioned in this article:
|
Click Here to Download the Subscriber Content |
{No standard content associated with this article} |
Comments:
[0]
[Show Disclaimer]
The information posted within the comments section are the opinions of its authors.
Such opinions may not be accurate and they are to be used at your own risk. Dx21, LLC cannot verify the validity of the
statements made within the posted comments. ¶ Messages that harass, abuse or threaten other members; have obscene or otherwise objectionable content; have spam,
commercial or advertising content will be removed. Please do not post any private information unless you want it to
be available publicly. Never assume that you are completely anonymous and cannot be identified by your posts.
|