ImageListPopup,一个 C# 类,弹出一个窗口以从图像列表中选择图像






4.83/5 (41投票s)
2003 年 2 月 24 日
2分钟阅读

183113

1345
您是否曾经想显示一个看起来像 MSN Messenger 表情符号选择器的图像列表...
引言
ImageListPopup
是一个非常易于使用的 Class
,它继承自 System.Windows.Forms.Form
,并允许显示一个弹出窗口,显示指定图像列表的内容。当您单击图像时,会触发一个事件,您可以获得单击的图像在 imagelist
中的索引。
特点
ImageListPopup
类支持
- 网格、背景颜色和选择颜色的自定义颜色
- 图像之间可调整的水平和垂直间距
兼容性
这个类是独立的,不需要任何特定的库,除了 .NET 默认的库。它在托管代码中运行,因此应该是可移植的。
如何使用该类
- 首先,将 *ImageListPopup.cs* 复制到您的项目目录中。
- 在您的源代码顶部添加指令
using CustomUIControls;
- 在您的类中添加一个成员变量
ImageListPopup imageListPopup;
- 在您的构造函数中,添加以下行
imageListPopup = new ImageListPopup(); // facultative properties 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);
详细说明
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);
这些属性允许我们自定义 ImageList Popup
的不同颜色(有关详细信息,请参见下图)
必须在调用 Init()
**之前**设置这些属性,否则它们将不会被考虑。
imageListPopup.EnableDragDrop = true;
此属性允许启用拖放支持(默认为 false
)。您可以将位图从弹出窗口拖到任何拖放目标。一个 Bitmap
对象和一个包含 imagelist
中已删除图像的 Id
的 string
可供目标使用。
imageListPopup.Init(imageList,8,8,5,4);
此行设置图像列表、2 个图像之间的水平和垂直像素间距以及行数和列数(必须存在)。
imageListPopup.ItemClick += new ImageListPopupEventHandler(OnItemClicked);
这是选择图像时触发的 Event
。委托应如下所示
private void OnItemClicked(object sender, ImageListPopupEventArgs e)
{
label1.Text = "Selected Image: " + e.SelectedItem;
}
当您想要显示 ImageListPopup
时,只需调用
imageListPopup.Show(x,y);
技术问题
当调用 Init
时,会生成一个预先计算的位图,其中包含所有 static
绘图(背景 Color
、网格和所有图像)。
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;
}
在 PaintBackground
方法中,我们将先前生成的位图绘制到一个隐藏的位图上,然后我们绘制选择矩形,最后,我们使用基本的双缓冲技术将所有内容绘制到屏幕上。
protected override void OnPaintBackground(PaintEventArgs pea)
{
Graphics grfx = pea.Graphics;
grfx.PageUnit = GraphicsUnit.Pixel;
// Basic double buffering technique
Bitmap offscreenBitmap = new Bitmap(_nBitmapWidth, _nBitmapHeight);
Graphics offscreenGrfx = Graphics.FromImage(offscreenBitmap);
// We blit the precalculated bitmap on the offscreen Graphics
offscreenGrfx.DrawImage(_Bitmap, 0, 0);
if (_nCoordX!=-1 && _nCoordY!=-1 &&
(_nCoordY*_nColumns+_nCoordX)<_imageList.Images.Count)
{
// We draw the selection rectangle
offscreenGrfx.FillRectangle(new SolidBrush(BackgroundOverColor),
_nCoordX*_nItemWidth + 1,
_nCoordY*_nItemHeight + 1,
_nItemWidth-1, _nItemHeight-1);
if (_bIsMouseDown)
{
// Mouse Down aspect for the image
_imageList.Draw(offscreenGrfx,
_nCoordX*_nItemWidth + _nHSpace/2 + 1,
_nCoordY*_nItemHeight + _nVSpace/2 + 1,
_imageList.ImageSize.Width,
_imageList.ImageSize.Height,
_nCoordY*_nColumns + _nCoordX);
}
else
{
// Normal aspect for the image
_imageList.Draw(offscreenGrfx,
_nCoordX*_nItemWidth + _nHSpace/2,
_nCoordY*_nItemHeight + _nVSpace/2,
_imageList.ImageSize.Width,
_imageList.ImageSize.Height,
_nCoordY*_nColumns + _nCoordX);
}
// Border selection Rectangle
offscreenGrfx.DrawRectangle(new Pen(BorderColor),
_nCoordX*_nItemWidth,
_nCoordY*_nItemHeight,
_nItemWidth, _nItemHeight);
}
// We blit the offscreen image on the screen
grfx.DrawImage(offscreenBitmap, 0, 0);
}
结论
我希望这段代码对您有用。如果您有任何建议来增强此类的功能,请发表评论。
更新
- 2003 年 2 月 24 日:初始版本
- 2003 年 2 月 25 日:添加了键盘支持,添加了拖放支持(默认情况下禁用)- 选择的图像及其 Id 可供拖放目标使用
许可证
本文未附加明确的许可证,但可能在文章文本或下载文件本身中包含使用条款。如有疑问,请通过下面的讨论区联系作者。
作者可能使用的许可证列表可以在此处找到。