65.9K
CodeProject 正在变化。 阅读更多。
Home

扩展 ListBox 以显示更复杂的项

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.57/5 (12投票s)

2006 年 9 月 4 日

2分钟阅读

viewsIcon

148499

downloadIcon

11044

本文展示了如何扩展 ListBox 以显示更复杂的项目 - 例如,带有图像和文本区域的项目。

exListBox screenshot

引言

是否曾经想为您的 Windows Forms 应用程序提供一个轻量级的列表框控件来列出自定义项目,例如,以一种漂亮的方式列出相册 - 带有相册封面图像、相册名称和详细信息,例如相册中有多少张照片等等? 我一直对DataGridView感到失望,在某些情况下它是一个很好的组件,但通常你只需要一个清晰的列表,这就是我提出这个扩展的exListBox的原因。

背景

我认为每个人都注意到标准的 Windows Forms ListBox 项是一个 object 类型,而不是一个 string。 如果您尝试将您的业务对象传递给 ListBox.Items,它不会理解您希望如何显示它,并且只会打印出您的对象的类名。 但有一个解决方案 - 覆盖 OnDrawItem 事件,并放置您自己的绘图过程。 顺便说一句,我尽量使代码尽可能短且易于理解,因此,我没有实现真正的数据绑定,一些构造函数/属性不在正确的位置,等等。

使用代码

您需要两个类 - exListBoxexListBoxItem。 第一个类派生自 ListBox 只是为了覆盖 OnDrawItem 事件,虽然您可以在不创建单独的类的情况下执行此操作,只需在您的表单源代码中处理 onDrawItem 事件,但如果您将在多个表单上使用扩展的 ListBox,最好将代码放在单独的代码文件中。 第二个类 (exListBoxItem) 是从头开始创建的,它有它的绘图过程和需要在列表中显示的元素。 在当前的示例中,一个项目包含一个图像、项目标题和项目详细信息,但您可以轻松地使用您自己的代码扩展 exListBoxItem 并拥有您自己的元素。

添加新项目很容易

Image myImage = new Image.FromFile("image.jpg");
int id = 1;
myExListBox.Items.Add(new exListBoxItem(id, "title", "details", myImage));

正如你所看到的,我在 exListBoxItem 中放置了一个额外的变量 - id,它应该帮助你将 exListBox 与你的数据库绑定。 我没有进行任何真正的数据绑定,以保持代码小巧、易于理解,并且易于编辑以适应您的需求。

ExListBoxItem selected = (myExListBoxItem)myExListBox.SelectedItem;
int id = selected.Id;

如果您想更改项目绘图中使用的字体或图像大小,您应该为您的 exListBox 调用新的构造函数

myExListBox = new exListBox(new Font(this.Font, FontStyle.Bold), 
              this.Font, new Size (100, 80), 
              StringAlignment.Near, StringAlignment.Near);

如果您更改了绘图过程,您应该注意一些事情。 首先,您需要检查您将要绘制的项目是否被选中。 正如您从方法标题中看到的,我正在 DrawItemEventArgs 中获取有关所选项目的信息。 在这里,我可以找到项目是否被选中以及我必须绘制该项目的项目边界。 所有其他参数仅在我的情况下才是必需的。 如果您的 exListBoxItem 包含其他元素,它可能看起来有点不同。

public void drawItem(DrawItemEventArgs e, Padding margin, 
       Font titleFont, Font detailsFont, StringFormat aligment, 
       Size imageSize)
{            

    if ((e.State & DrawItemState.Selected) == DrawItemState.Selected)
    {
        // if selected, mark the background differently
    }
    else
    {
        // mark as unselected or just don't make anything
    }

    // draw some item separator
    e.Graphics.DrawLine(Pens.DarkGray, e.Bounds.X, e.Bounds.Y, 
                        e.Bounds.X + e.Bounds.Width, e.Bounds.Y);

    // draw item elements

    ...
    // put some focus rectangle
    e.DrawFocusRectangle();
}

历史

  • 1.0 - 文章出现。
© . All rights reserved.