Introduction
The ImageListPopup
is quite easy to use Class
that inherits from System.Windows.Forms.Form
and allows to show a popup displaying the content of a specified Image List. When you click over an image, an event is fired and you get the index of the clicked image in the imagelist
.
Features
The ImageListPopup
class supports:
- Custom colors for the grid, background color and selection color
- Adjustable horizontal and vertical spaces between images
Compatibility
This class is stand alone and doesn't need any particular libraries except .NET default ones. It runs in managed code and hence should be portable.
How to Use the Class
- First of all, copy ImageListPopup.cs in your project directory.
- Add on the top of your source code, the directive
using CustomUIControls;
- Add a member variable in your class:
ImageListPopup imageListPopup;
- In your constructor, add the following lines:
imageListPopup = new ImageListPopup();
imageListPopup.BackgroundColor = Color.FromArgb(241,241,241);
imageListPopup.BackgroundOverColor = Color.FromArgb(102,154,204);
imageListPopup.HLinesColor = Color.FromArgb(182,189,210);
imageListPopup.VLinesColor = Color.FromArgb(182,189,210);
imageListPopup.BorderColor = Color.FromArgb(0,0,0);
imageListPopup.EnableDragDrop = true;
imageListPopup.Init(imageList,8,8,5,4);
imageListPopup.ItemClick += new ImageListPopupEventHandler(OnItemClicked);
Details
imageListPopup.BackgroundColor = Color.FromArgb(241,241,241);
imageListPopup.BackgroundOverColor = Color.FromArgb(102,154,204);
imageListPopup.HLinesColor = Color.FromArgb(182,189,210);
imageListPopup.VLinesColor = Color.FromArgb(182,189,210);
imageListPopup.BorderColor = Color.FromArgb(0,0,0);
These properties allow us to customize the different colors of the ImageList Popup
(see the picture below for details):
The properties must be set before calling Init()
, otherwise they won't be taken into account.
imageListPopup.EnableDragDrop = true;
This property allows to Enable Drag'n'Drop support (default is false
). You can drag a bitmap from the popup to any Drop target. A Bitmap
object and a string
containing the Id
of the dropped image in the imagelist
are available to the target.
imageListPopup.Init(imageList,8,8,5,4);
This line sets the image list, the horizontal and vertical pixel spaces between 2 images, and the rows and columns number (must be present).
imageListPopup.ItemClick += new ImageListPopupEventHandler(OnItemClicked);
This is the Event
that is fired when an image is selected. The delegate should look like this:
private void OnItemClicked(object sender, ImageListPopupEventArgs e)
{
label1.Text = "Selected Image: " + e.SelectedItem;
}
When you want to show the ImageListPopup
, you just have to call:
imageListPopup.Show(x,y);
Technical Issues
When Init
is called, a pre-calculated bitmap is generated with all the static
drawing (the background Color
, the grid, and all the images).
public bool Init(ImageList imageList, int nHSpace, int nVSpace,
int nColumns, int nRows)
{
_imageList = imageList;
_nColumns = nColumns;
_nRows = nRows;
_nHSpace = nHSpace;
_nVSpace = nVSpace;
_nItemWidth = _imageList.ImageSize.Width + nHSpace;
_nItemHeight = _imageList.ImageSize.Height + nVSpace;
_nBitmapWidth = _nColumns * _nItemWidth + 1;
_nBitmapHeight = _nRows * _nItemHeight + 1;
this.Width = _nBitmapWidth;
this.Height = _nBitmapHeight;
_Bitmap = new Bitmap(_nBitmapWidth,_nBitmapHeight);
Graphics grfx = Graphics.FromImage(_Bitmap);
grfx.FillRectangle(new SolidBrush(BackgroundColor), 0, 0,
_nBitmapWidth, _nBitmapHeight);
for (int i=0;i<_nColumns;i++)
grfx.DrawLine(new Pen(VLinesColor), i*_nItemWidth, 0,
i*_nItemWidth, _nBitmapHeight-1);
for (int i=0;i<_nRows;i++)
grfx.DrawLine(new Pen(HLinesColor), 0,
i*_nItemHeight, _nBitmapWidth-1, i*_nItemHeight);
grfx.DrawRectangle(new Pen(BorderColor), 0 ,0 ,
_nBitmapWidth-1, _nBitmapHeight-1);
for (int i=0;i<_nColumns;i++)
for (int j=0;j<_nRows ;j++)
if ((j*_nColumns+i) < imageList.Images.Count)
imageList.Draw(grfx,
i*_nItemWidth+_nHSpace/2,
j*_nItemHeight+nVSpace/2,
imageList.ImageSize.Width,
imageList.ImageSize.Height,
j*_nColumns+i);
return true;
}
In the PaintBackground
method, we blit the previously generated bitmap onto a hidden bitmap, then we draw the selection rectangle, and finally we blit everything to the screen with a basic double buffering technique.
protected override void OnPaintBackground(PaintEventArgs pea)
{
Graphics grfx = pea.Graphics;
grfx.PageUnit = GraphicsUnit.Pixel;
Bitmap offscreenBitmap = new Bitmap(_nBitmapWidth, _nBitmapHeight);
Graphics offscreenGrfx = Graphics.FromImage(offscreenBitmap);
offscreenGrfx.DrawImage(_Bitmap, 0, 0);
if (_nCoordX!=-1 && _nCoordY!=-1 &&
(_nCoordY*_nColumns+_nCoordX)<_imageList.Images.Count)
{
offscreenGrfx.FillRectangle(new SolidBrush(BackgroundOverColor),
_nCoordX*_nItemWidth + 1,
_nCoordY*_nItemHeight + 1,
_nItemWidth-1, _nItemHeight-1);
if (_bIsMouseDown)
{
_imageList.Draw(offscreenGrfx,
_nCoordX*_nItemWidth + _nHSpace/2 + 1,
_nCoordY*_nItemHeight + _nVSpace/2 + 1,
_imageList.ImageSize.Width,
_imageList.ImageSize.Height,
_nCoordY*_nColumns + _nCoordX);
}
else
{
_imageList.Draw(offscreenGrfx,
_nCoordX*_nItemWidth + _nHSpace/2,
_nCoordY*_nItemHeight + _nVSpace/2,
_imageList.ImageSize.Width,
_imageList.ImageSize.Height,
_nCoordY*_nColumns + _nCoordX);
}
offscreenGrfx.DrawRectangle(new Pen(BorderColor),
_nCoordX*_nItemWidth,
_nCoordY*_nItemHeight,
_nItemWidth, _nItemHeight);
}
grfx.DrawImage(offscreenBitmap, 0, 0);
}
Conclusion
I hope this code will be useful to you. If you have suggestions to enhance the functionalities of this class, please post a comment.
Updates
- 24/02/2003: Initial release
- 25/02/2003: Added Keyboard support, added Drag'n'Drop support (disabled by default) - the selected Image and its Id are available to the drop target
License
This article has no explicit license attached to it, but may contain usage terms in the article text or the download files themselves. If in doubt, please contact the author via the discussion board below.
A list of licenses authors might use can be found here.
I live in San Jose CA and work as a UI architect for Meta Integration Technology