2013-12-20 84 views
3

我设法自定义带有图像的正常列表框,当在ownerdrawn中选择项目时更改文本和背景颜色,我现在想要实现的是在项目上绘制自定义突出显示颜色当鼠标悬停是在列表框上的项目,是可能或不...,我提供我下面的示例代码是什么我走了这么远..鼠标悬停在项目上时突出显示列表框项目

If e.Index = -1 Then Exit Sub 
     Dim listBox As ListBox = CType(sender, ListBox) 
     e.DrawBackground() 
     Dim isItemSelected As Boolean = ((e.State And DrawItemState.Selected) = DrawItemState.Selected) 
     If e.Index >= 0 AndAlso e.Index < listBox.Items.Count Then 
      Dim textSize As SizeF = e.Graphics.MeasureString(listBox.Items(e.Index).ToString(), listBox.Font) 
      Dim itemImage As Image = My.Resources.FolderHorizontal 
      'set background and text color 
      Dim backgroundColorBrush As New SolidBrush(If((isItemSelected), Color.CornflowerBlue, Color.White)) 
      Dim itemTextColorBrush As Color = If((isItemSelected), Color.White, Color.Black) 

      e.Graphics.FillRectangle(backgroundColorBrush, e.Bounds) 
      'draw the item image 
      e.Graphics.SmoothingMode = SmoothingMode.HighQuality 
      e.Graphics.DrawImage(itemImage, e.Bounds.X + 2, _ 
           e.Bounds.Y + (e.Bounds.Height - textSize.Height)/2, _ 
           itemImage.Width, itemImage.Height) 
      'draw the item text 
      Dim x, y As Single 
      Dim h As Single = textSize.Height 
      Dim rect As Rectangle = e.Bounds 
      rect.X += listBox.ItemHeight 
      rect.Width -= listBox.ItemHeight 

      x = rect.X - 3 
      y = rect.Y + (rect.Height - h)/2 

      Dim itemText As String = listBox.Items(e.Index).ToString() 
      TextRenderer.DrawText(e.Graphics, itemText, e.Font, _ 
            New Rectangle(x, y, ClientRectangle.Width, ClientRectangle.Height), _ 
            itemTextColorBrush, TextFormatFlags.Default) 
      'clean up 
      backgroundColorBrush.Dispose() 

     End If 
     e.DrawFocusRectangle() 

回答

2

可以使用IndexFromPoint做这样的事情:

Dim mouseIndex As Integer = -1 

Private Sub ListBox1_MouseMove(sender As Object, e As MouseEventArgs) _ 
           Handles ListBox1.MouseMove 
    Dim index As Integer = ListBox1.IndexFromPoint(e.Location) 
    If index <> mouseIndex Then 
    If mouseIndex > -1 Then 
     Dim oldIndex As Integer = mouseIndex 
     mouseIndex = -1 
     If oldIndex <= ListBox1.Items.Count - 1 Then 
     ListBox1.Invalidate(ListBox1.GetItemRectangle(oldIndex)) 
     End If 
    End If 
    mouseIndex = index 
    If mouseIndex > -1 Then 
     ListBox1.Invalidate(ListBox1.GetItemRectangle(mouseIndex)) 
    End If 
    End If 
End Sub 

然后在您的图纸代码中:

If mouseIndex > -1 AndAlso mouseIndex = e.Index Then 
    backgroundColorBrush = New SolidBrush(Color.DarkMagenta) 
End If 
+0

感谢,它的工作的......有一点小问题,我该如何最小化闪烁,我认为它重绘每次移动时鼠标放在物品上,或者有另一种方式做...但除此之外,它的效果很好 – mercenary

+0

@mercenary ListBox控件相当无法控制地闪烁着快乐,但我更新了该帖子以减少其中的一些内容。考虑使用ListView控件。 – LarsTech

+0

谢谢,我在想使用listview,也许在下一个版本的工具,它的文件夹图标转换器使用列表框一次容纳多个文件夹... – mercenary

1

我会告诉你如何做到这一点。所有专家说,它的复杂,不能用列表框来完成......我能做到这一点在5分钟内

我创建的列表框中的名称是listPOSSIBILITIES

1)创建一个变量,它是全局的表单

Dim HOVERTIME As Boolean = True 

2)创建MouseEnter事件

私人小组listPOSSIBILITIES_MouseEnter(发送者为对象,例如作为system.EventArgs)把手listPOSSIBILITIES.MouseEnter

HOVERTIME = True 

结束子

3)创建鼠标离开事件

私人小组listPOSSIBILITIES_MouseLeave(发送者为对象,例如作为System.EventArgs)把手listPOSSIBILITIES.MouseLeave

HOVERTIME = False 

结束子

4)创建MouseMove事件

私人小组listPOSSIBILITIES_MouseMove(发送者为对象,例如作为System.Windows.Forms.MouseEventArgs)把手listPOSSIBILITIES.MouseMove

Dim mypoint As Point 
    mypoint = listPOSSIBILITIES.PointToClient(Cursor.Position) 
    Dim myindex As Integer = listPOSSIBILITIES.IndexFromPoint(mypoint) 
    If myindex < 0 Then Exit Sub 
    listPOSSIBILITIES.SelectedIndex = myindex 

结束子

5)创建MouseClick事件

私人小组listPOSSIBILITIES_MouseClick( sender As Object,e As System.Windows.Forms.MouseEventArgs)Handles listPOSSIBILITIES.MouseClick

HOVERTIME = False 

结束子

6)创建SelectedIndexChanged事件

私人小组listPOSSIBILITIES_SelectedIndexChanged(发件人为System.Object的,例如作为System.EventArgs)把手listPOSSIBILITIES。的SelectedIndexChanged

If HOVERTIME Then Exit Sub 

    'put the rest of your code after this above If statement 

这工作,因为鼠标点击事件在SelectIndexChanged事件之前引发

相关问题