×

Net Frame Work SDK 为在VB.Net实现个性化ListBox提供的工具

Kalet Kalet 发表于2009-03-20 12:00:13 浏览294 评论0

抢沙发发表评论

1. 属性:

  在缺省情况下,ListBox是不允许被重绘制的,这是因为ListBox中的“DrawMode”属性值是“Normal”。此属性的作用是设定ListBox的绘制模式,“Normal”是枚举DrawMode中的一个成员。设定为“Normal”意味着ListBox中各个成员都是系统控制,并且各项大小相等。“DrawMode”属性在本文中的作用类似与上一文中的“OwnerDraw”属性。枚举DrawMode中的其他成员请参阅表01所示:Net Frame Work SDK 为在VB.Net实现个性化ListBox提供的工具
















属性

说明
Normal组件的所有元素都由操作系统绘制,并且元素大小都相等。
OwnerDrawFixed组件的所有元素都是手动绘制的,并且元素大小都相等。
OwnerDrawVariable组件的所有元素都由手动绘制,元素大小可能不相等。
                 表01:枚举DrawMode中的成员及其说明

  本文设定ListBox的“DrawMode”属性值是“OwnerDrawVariable”。因为本文介绍的程序不仅绘制ListBox中的各元素,还将设定ListBox中元素的大小。

  2. 事件:

  在设定“DrawMode”属性值为“OwnerDrawVariable”后,将会触发一些用以绘制ListBox的事件,如:DrawItem事件和MeasureItem事件。DrawItem事件主要处理绘制ListBox中的各个元素,MeasureItem事件主要是处理设置ListBox各元素的大小。ListBox中的DrawItem事件和MeasureItem事件和上一节中介绍的MenuItem的DrawItem事件和MeasureItem事件是一样的,分别接收DrawItemEventArgs参数和MeasureItemEventArgs参数数据,并以此数据来处理。这二个事件的详细介绍请参阅前一节中内容。

  3. 绘制图形的方法:

  在绘制ListBox时所采用的方法和上一节中也基本相同,唯一不同的是在本文中增加了图形绘制方法DrawImage,DrawImage方法的作用是在指定的位置,以指定图形的原始大小进行绘制,本文通过DrawImage方法实现在ListBox各项中增加相应的图形。

  二.设计、调试和运行环境:

  (1).微软公司视窗2000服务器版。

  (2).Visual Studio .Net 2003企业构建版,.Net FrameWork SDK 1.1版本号4322。

  三.循序渐进绘制自己的ListBox:

  首先还是按照以下步骤新建一个Visual Basic .Net项目,并在项目窗体上增加一个ListBox组件:

  1. 启动Visual Studio .Net。

  2. 选择菜单【文件】|【新建】|【项目】后,弹出【新建项目】对话框。

  3. 将【项目类型】设置为【Visual Basic项目】。

  4. 将【模板】设置为【Windows应用程序】。

  5. 在【名称】文本框中输入【打造自己的ListBox】。

  在【位置】的文本框中输入【E:\VS.NET项目】,然后单击【确定】按钮,这样在“E:\VS.NET项目”目录中就产生了名称为“打造自己的ListBox”的文件夹,并在里面创建了名称为“打造自己的ListBox”的项目文件。

  6. 把Visual Studio .Net的当前窗口切换到【Form1.vb(设计)】窗口,并从【工具箱】中的【Windows窗体组件】选项卡中往Form1窗体中拖入一个ListBox组件到窗体中。并设定此ListBox组件中加入“aaa”、“bbb”和“ccc”三个项。

  至此一个最典型的ListBox就完成了。具体如图01所示:







图01:【打造自己的ListBox】项目设计界面之一
下面就在此ListBox基础上,对其进行改造,加入个性化的东西,首先是对ListBox中的各项的字体、颜色等等进行改造。修改ListBox字体和颜色是通过DrawItem事件来实现的,使用DrawString方法把指定字体、大小、颜色在指定区域绘制文字。设定ListBox各元素的大小是通过MeasureItem事件实现的。以下是实现上述改造的具体操作步骤:

  1. 设定ListBox组件的“DrawMode”属性值为“OwnerDrawVariable”。此时会发现在ListBox组件加入的“aaa”、“bbb”和“ccc”三项均不显示。这是因为当ListBox组件的“DrawMode”属性值为“OwnerDrawVariable”,绘制ListBox的工作将不在由机器自动完成,而是通过ListBox的DrawItem事件来实现。

  2. 把Visual Studio .Net的当前窗口切换到Form1.vb的代码编辑窗口。

  3. 在定义窗体组件的代码区中添加下列代码,下列代码是定义二个数组,此数组的成员分别是设定ListBox中各项的名称和定义各项名称的颜色。





Private sData ( ) As String = {"红色" , "蓝色" , "黄色" , "绿色" , "黄绿色" , "灰色"}
'此数组是定义ListBox中各项的名称
Private sColorData ( ) As Object = {System.Drawing.Color.Red , System.Drawing.Color.Blue , System.Drawing.Color.Yellow , System.Drawing.Color.Green , System.Drawing.Color.YellowGreen , System.Drawing.Color.SlateGray}
'此数组是定义各项名称对应的颜色

  4. 在InitializeComponent过程中的代码后部添加下列代码,下列代码是以上面定义的sData数组来设定ListBox的各项名称:





listBox1.DataSource = sData

  5. 在InitializeComponent过程之后添加下列代码,下列代码是定义ListBox的DrawItem事件,通过此事件对ListBox中各项进行重新绘制:





Private Sub listBox1_DrawItem ( ByVal sender As Object , ByVal e As System.Windows.Forms.DrawItemEventArgs )  Handles listBox1.DrawItem
 Dim datas As String ( ) = sData
 Dim rc As RectangleF = New RectangleF ( e.Bounds.X + 1 , e.Bounds.Y + 1 , e.Bounds.Width - 5 , e.Bounds.Height - 3 )
 Dim rc1 As Rectangle = New Rectangle ( e.Bounds.X + 1 , e.Bounds.Y + 1 , e.Bounds.Width - 5 , e.Bounds.Height - 3 )
 e.DrawBackground ( )
 '在选定项目上绘制选定背景色
 'e.DrawFocusRectangle ( )
 Dim sf As StringFormat = New StringFormat ( )
 sf.Alignment = StringAlignment.Center
 '设定ListBox中项目名称的在矩形区域的排列对齐方式
 e.Graphics.DrawRectangle ( New Pen ( New SolidBrush ( System.Drawing.Color.Black ) , 1 ) , rc1 )
 '以线条粗度为1,黑色画笔对绘制ListBox中的每一个项目的边框
 e.Graphics.DrawString ( sData ( e.Index ) , New Font ( FontFamily.GenericSansSerif , 14 , FontStyle.Bold ) , New SolidBrush ( sColorData ( e.Index ) ) , rc , sf )
 ' 以指定的字体大小、类型、颜色绘制ListBox项目名称Net Frame Work SDK 为在VB.Net实现个性化ListBox提供的工具
End Sub

  6. 在ListBox的DrawItem事件代码之后添加下列代码,下列代码是定义ListBox的MeasureItem事件,此事件的作用是设定ListBox的各元素的大小:





Private Sub listBox1_MeasureItem ( ByVal sender As Object , ByVal e As System.Windows.Forms.MeasureItemEventArgs ) Handles listBox1.MeasureItem
 e.ItemHeight = 25
End Sub

  至此重新绘制的ListBox第一步就完成了,保存上述的修改后,单击快捷键F5,改造后的ListBox如图02所示:







图02:【打造自己的ListBox】项目运行界面之一
下面就要实现为图02中的每一项加入一个图片,加入图片的是通过DrawImage方法

  在各项的指定位置绘制相应的图象,所以首先要确定上述六项对应的图象图片所在的位置,方便起见,这六个图片文件都和此项目编译后的文件在同一目录。名称分别为“fileOpen.bmp”、“exit.bmp”、“close.bmp”、“about.bmp”、“about.bmp”和“network.bmp”。下面步骤就是在上述基础上为各项加入图片:

  1. 在定义窗体组件的代码区中再添加下列代码,下列代码是定义六个Bitmap对象:





Dim img_fileopen , img_exit , img_close , img_security , img_network , img_about As Bitmap

  2. 在InitializeComponent过程中的代码后部添加下列代码,下列代码是初始化上面创建的Bitmap对象:





'运行程序前确认在文件当前目录存在以下六个BMP文件
img_fileopen = New Bitmap ( "fileOpen.bmp" )
img_exit = New Bitmap ( "exit.bmp" )
img_close = New Bitmap ( "close.bmp" )
img_about = New Bitmap ( "about.bmp" )
img_security = New Bitmap ( "about.bmp" )
img_network = New Bitmap ( "network.bmp" )

  3. 用下列代码替换Form1.vb中的ListBox1的DrawItem事件对应的代码,下列代码是重新定义ListBox1的DrawItem事件,其中增加了为ListBox1中各项添加图片的功能:





Private Sub listBox1_DrawItem ( ByVal sender As Object , ByVal e As System.Windows.Forms.DrawItemEventArgs ) Handles listBox1.DrawItem
 Dim datas As String ( ) = sData
 Dim rc As RectangleF = New RectangleF ( e.Bounds.X + 1 , e.Bounds.Y + 1 , e.Bounds.Width - 5 ,  e.Bounds.Height - 3 )
 Dim rc1 As Rectangle = New Rectangle ( e.Bounds.X + 1 , e.Bounds.Y + 1 , e.Bounds.Width - 5 , e.Bounds.Height - 3 )
 e.DrawBackground ( )
 '在选定项目上绘制选定背景色
 'e.DrawFocusRectangle ( )
 Dim sf As StringFormat = New StringFormat ( )
 sf.Alignment = StringAlignment.Center
 '设定ListBox中项目名称的在矩形区域的排列对齐方式
 e.Graphics.DrawRectangle ( New Pen ( New SolidBrush ( System.Drawing.Color.Black ) , 1 ) , rc1 )
 '以线条粗度为1,黑色画笔对绘制ListBox中的每一个项目的边框
 e.Graphics.DrawString ( sData ( e.Index ) , New Font ( FontFamily.GenericSansSerif , 14 , FontStyle.Bold ) , New SolidBrush ( sColorData ( e.Index ) ) , rc , sf )
 ' 以指定的字体大小、类型、颜色绘制ListBox项目名称
 Dim useImage As Image = Nothing
 '创建、初始化一个Image实例
 '以下是代码是在ListBox上绘制图片
 If ( datas ( e.Index ) = "红色" ) Then
  useImage = img_fileopen
 End If
 If ( datas ( e.Index ) = "蓝色" ) Then
  useImage = img_close
 End If
 If ( datas ( e.Index ) = "黄色" ) Then
  useImage = img_exit
 End If
 If ( datas ( e.Index ) = "绿色" ) Then
  useImage = img_security
 End If
 If ( datas ( e.Index ) = "黄绿色" ) Then
  useImage = img_network
 End If
 If ( datas ( e.Index ) = "灰色" ) Then
  useImage = img_about
 End If

 If ( useImage Is Nothing ) = False Then
  Dim sz As SizeF = New SizeF
  sz = useImage.PhysicalDimension ( )
  '获取此Image实例的宽度和高度。
  e.Graphics.DrawImage ( useImage , e.Bounds.X + 5 , CInt ( ( e.Bounds.Bottom + e.Bounds.Top ) / 2 - sz.Height / 2 ) )
  '在制定的位置按照原始大小绘制图片
 End If
End Sub

  保存上述步骤后,单击快捷键F5,本文绘制后的ListBox如图03所示:







图03:【打造自己的ListBox】项目运行界面之二

  四.总结:
Net Frame Work SDK 为在VB.Net实现个性化ListBox提供的工具
  通过本文可见,手动绘制Windows窗体组件并不像想像的那么复杂。由于.Net FrameWork SDK已经为Visual Basic .Net提供了许多绘制Windows窗体组件的“工具”,只要掌握Windows组件事件的处理过程和正常处理事件接收的参数中的数据,运用各种图形、图象的绘制方法,再加上精心的编排,就基本能够“改造”任何Windows窗体组件。


群贤毕至

访客