![]() |
Desktop Development »
Miscellaneous »
Miscellaneous Controls
Intermediate
License: The Code Project Open License (CPOL)
Filmstrip control for Windows FormsBy callisthenesAn article describing a C# Filmstrip control designed for Windows forms |
C# (C# 2.0), Windows, .NET (.NET 2.0), Win32, WinForms, Dev
|
||||||||||
|
Advanced Search |
|
|
|
||||||||||||||||

Whilst there seems to be a number of feature-rich filmstrip controls available for web applications, there are precious few for normal windows forms applications. I did read rahulparthe's article but that did not provide the required functionality. So my effort here has been developed from the ground up with no other inspiration.
The control is built into it's own dll, Filmstrip.dll, and uses the Filmstrip namespace. You can add a reference to the compiled dll or you can directly copy the source files to a folder on your project. The code is currently designed so you can just copy the source files, it doesn't need any extra resources. (This means displayable strings are hard-coded as constants rather than in the string table as they should be.) Once the reference has been added, ensure that it appears in the toolbox, then simply drag the control onto a form.
The Filmstrip control has the following features:
Space key. The Home, End, PageUp and PageDown keys are also supported. The accelerator combination to display the edit description form is also customisable. FilmstripControl onto a form. // Using the AddImage overloads
filmstripControl.AddImage(
new FilmstripImage(Properties.Resources.Zugspitze as Image,
"Zugspitze, Germany"));
filmstripControl.AddImage(Properties.Resources.ChobeSunset as Image,
"Sunset at Chobe National Park, Zambia");
// Or adding many images, chosen from an OpenFileDialog...
if (DialogResult.OK == openFileDialog.ShowDialog())
{
List<FilmstripImage> images = new List<FilmstripImage>();
foreach (String file in openFileDialog.FileNames)
{
Image thisImage = Image.FromFile(file);
FilmstripImage newImageObject =
new FilmstripImage(thisImage, file);
images.Add(newImageObject);
}
filmstripControl.AddImageRange(images.ToArray());
}
The Filmstrip control has a number of public properties. These can be categorised into 2 areas: visual and functional.
The visual properties are used to modify/customise the visual look and feel of the control. It is possibly to change the background colour of the entire control (and also the colour of the selected hightlight), to replace the left and right navigational buttons with custom images and to specify where the thumbnail strip is displayed among other things.
| Property | Read only? | Description |
ControlBackground |
No | Specifies the background colour of all items on the filmstrip control. Default value is 'Control'. |
EditDescriptionAccelerator |
No | Sets the accelerator key combination to display the edit description form for the currently selected image. Default is Ctrl+D. |
ImageNavLeft |
No | Specifies the image to be used for the left navigation button. If no image is specified the button text will have '<'. |
ImageNavLeftLayout |
No | Specifies the image layout used for the left navigation button image, if an image is present. Default value is 'Stretch'. |
ImageNavRight |
No | Specifies the image to be used for the right navigation button. If no image is specified the button text will have '>'. |
ImageNavRightLayout |
No | Specifies the image layout used for the right navigation button image, if an image is present. Default value is 'Stretch'. |
MainImageLayout |
No | Specifies the image layout for the image selected into the main viewing area. Default value is 'Center'. |
ScrollHoverDelay |
No | Specifies the delay interval (in milliseconds) used before scolling the thumbnail view whenever the mouse hovers over a navigation button. Default value is 500ms. |
SelectedHighlight |
No | Specifies the colour of the highlight surrounding the selected thumbnail image. Default value is 'DarkBlue'. |
ThumbsStripLocation |
No | Specifies the location of the strip of thumbnail images, either 'Top' or 'Bottom'. Default value is 'Bottom'. |
The functional properties relate to the data used by the control:
| Property | Read only? | Description |
ImagesCollection |
No | The images collection. Setting this property will remove any images currently in the collection. |
SelectedImage |
Yes | The image currently selected in the control. |
SelectedImageDescription |
No | The description of the image currently selected in the control. |
SelectedImageID |
No | Specifies the image id of the image currently selected in the control. |
The control has only a few public methods. These were kept to a minimum in order to retain simplicitiy and ease of use:
AddImage |
This method adds a single image to the control. The new image is added at the end of the control's internal collection. (3 overloads.) |
AddImageRange |
This method adds multiple images to the control. The new images are added at the end of the control's internal collection. |
ClearAllImages |
This method removes all images from the control. |
ClearSelection |
This method removes any selection from the control so that no image is selected. |
EnsureThumbIsVisible |
This method ensures that the thumb for the specified image is visible in the thumnbails strip. It does not affect the current selection. |
RemoveImage |
This method removes the specified image from the control. |
Note: At present, AddImage (all overloads), AddImageRange and RemoveImage all cause the entire thumbnails list to be repopulated, which does cause a slight flicker. It is advised that when adding many images after the control has been initially displayed (i.e. not in the OnLoad handler) use the AddImageRange method, as this will only cause the thumbnails list to be repopulated once.
The control fires 2 different events:
SelectionChanged |
This event is fired when the selected image in the control changes. |
SelectedImageDescriptionChanged |
This event is fired when the description of the selected image changes within the control. |
The Filmstrip.dll assembly contains the following public 'objects':
FilmstripControl |
The actual filmstrip control. |
FilmstripControl.StripLocation |
A simple enum used to specify the position of the thumbnails strip on the control. It currently only has values for 'Top' and 'Bottom'. |
FilmstripImage |
A simple class to encapsulate an image inside the control. |
Each image added to the control is stored internally as a FilmstripImage object in standard Dictionary. Each FilmstripImage has it's own ID - this is required and is a whole number. If an image id is not specified then one is generated during the AddImage call and returned to the caller. The only invalid value for an image id is -1: this is specified by the static class member NO_SELECTION_ID.
The most challenging aspect of developing the control has been ensuring that the collection of thumbnails is constructed, populated and rendered correctly, especially when the control is being resized.
The strip of thumbnails is dynamicaly created depending on the the number of images in the control's collection and the current size of the control. The entire strip, including navigation buttons, is contained on a panel so that it can be moved to the desired location on the control. On the strip itself the thumbnails themselves are located on another panel that is sandwiched between the 2 navigation buttons. The navigation buttons are of fixed size and position - i.e. they maintain their position relative to the sides of the control. In this way the panel containing the thumbnails grows or shrinks with the control. The control maintains a collection of all thumbnail Button objects currently in use - the thumbnailControls member.

Given that each thumbnail panel and button are a fixed size, it is possible to calculate the number of thumbnails that can fit into the parent panel at any time. Whenever the control width alters it checks to see if it is displaying the full number of thumbnails possible, and then adds or removes thumbnails as necessary. In either case we have to account for the fact that window hosting the form may have been maximised or 'un-maximised' so we may have to add or remove more than one thumbnail at a time. This is all done in the AdjustThumbnails function. So when the control gets bigger:
// Did we get bigger, and we have't yet created thumbs for all the images we have?
while ((thumbnailControls.Count < ThumbsForWidth())
&& (thumbnailControls.Count < imagesCollection.Count))
{
// Get the image id of the current last one
int imageIDOfLast = -1;
if (thumbnailControls.Count > 0)
{
imageIDOfLast =
Convert.ToInt32(thumbnailControls[thumbnailControls.Count - 1].Tag.ToString());
}
// Add a new one
int newIndex = PushThumbnail();
// If we're already at the right hand end, we need to shift all the images across
// (as if the left navigation button was clicked)
if ((imageIDOfLast > -1) && (keys[keys.Count - 1] == imageIDOfLast))
{
MoveThumbnailsLeft();
}
else
{
// Set the image on this new thumb
PopulateThumbnail(newIndex);
}
}
But thankfully when the control gets smaller the code is much simpler:
while (thumbnailControls.Count > ThumbsForWidth())
{
PopThumbnail();
}

The sample application provided demonstrates how the Filmstrip control can be easily integrated onto a form. It provides the following functionality:
There are a few things of note in the sample application:
All code was developed using Visual Studio 2005 Professional and Express editions on Windows XP (Home & Professional). It has not been fully tested using any other versions of Visual Studio, the .Net framework or on other operating systems, as I do not have access to them. (Although limited testing on earlier versions was done on Windows 2000 and Windows 2003 Server.)
EnsureThumbIsVisible method public. Home, End, PageUp and PageDown keys. SelectedImageDescription property now writeable. AddImage overload has been created, along with a new overloaded constructor for the FilmstripImage class. Additionally all AddImage methods now return the image id of the image added. If required, image ids can now be negative. The only value invalid value is -1, which is specified by the static member NO_SELECTION_ID.
General
News
Question
Answer
Joke
Rant
Admin
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 27 Jun 2008 Editor: |
Copyright 2008 by callisthenes Everything else Copyright © CodeProject, 1999-2009 Web15 | Advertise on the Code Project |