优化自定义列表框控件

时间:2013-10-12 00:52:36

标签: vb.net visual-studio listbox custom-controls listboxitems

我制作了一种自定义列表框,并且包含了为每个项目添加图像的功能。 我希望能够随意逐个更改这些图像,并且我不太确定如何去做。目前,您只能在每个项目中选择您想要的图像。

Public Class CustomListBox
Public label As Label
Public pic As PictureBox
Public panel As Panel
Public itemID As String
Public itemCollection As New Collection
Public bgColor As Color
Public txtEnterColor As Color = Color.FromArgb(80, 80, 80)
Public txtColor As Color = Color.FromArgb(150, 150, 150)
Public bgEntercolor As Color = Color.FromArgb(230, 230, 230)
Public x, y, paddingInt As Integer
Public itemHeight As Integer = 40
Public image As Image = My.Resources.FavNone
Public Event Item_Clicked()

Private Property ItemBackColor As Color
    Get
        Return BackColor
    End Get
    Set(ByVal value As Color)
        bgColor = value
    End Set
End Property

Private Property ItemPadding As Padding
    Get
        Return Padding
    End Get
    Set(ByVal value As Padding)
        Padding = value
    End Set
End Property

Public Property HoverBackColor As Color
    Get
        Return bgEntercolor
    End Get
    Set(ByVal value As Color)
        bgEntercolor = value
    End Set
End Property

Public Property ItemImage As Image
    Get
        Return image
    End Get
    Set(ByVal value As Image)
        image = value
    End Set
End Property

Public Property HoverTextColor As Color
    Get
        Return txtEnterColor
    End Get
    Set(ByVal value As Color)
        txtEnterColor = value
    End Set
End Property

Public Property TextColor As Color
    Get
        Return txtColor
    End Get
    Set(ByVal value As Color)
        txtColor = value
    End Set
End Property

Public Property TrueItemHeight As Integer
    Get
        Return itemHeight
    End Get
    Set(ByVal value As Integer)
        itemHeight = value
    End Set
End Property

Public Sub UpdateItems()
    For Each item As String In itemCollection
        label = New Label
        pic = New PictureBox
        panel = New Panel
        With pic
            .Width = itemHeight
            .Height = itemHeight
            .SizeMode = PictureBoxSizeMode.Zoom
            .Image = image
        End With
        With label
            .BackColor = (bgColor)
            .ForeColor = (txtColor)
            .Width = Me.Width - itemHeight
            .Height = itemHeight
            .Tag = item
            .Height = itemHeight
            .Padding = ItemPadding
            .Text = item
            .Left = itemHeight
            .TextAlign = ContentAlignment.MiddleLeft
            AddHandler label.MouseEnter, AddressOf Item_Enter
            AddHandler label.MouseLeave, AddressOf Item_Leave
            AddHandler label.MouseUp, AddressOf Item_Mousedown
        End With
        With panel
            .Location = New Point(x, y)
            .Width = Me.Width
            .Height = itemHeight
            .Controls.Add(pic)
            .Controls.Add(label)
            y += .Height + paddingInt
        End With
        Me.Controls.Add(panel)
    Next
End Sub

Private Sub Item_Enter(ByVal sender As Label, ByVal e As EventArgs)
    sender.BackColor = (bgEnterColor)
    sender.ForeColor = (txtEnterColor)
    itemID = sender.Tag
End Sub

Private Sub Item_Leave(ByVal sender As Label, ByVal e As EventArgs)
    sender.BackColor = (bgColor)
    sender.ForeColor = (txtColor)
End Sub

Private Sub Item_Mousedown(ByVal sender As Label, ByVal e As MouseEventArgs)
    Select Case e.button
        Case Windows.Forms.MouseButtons.Left
            RaiseEvent Item_Clicked()
    End Select
End Sub

End Class

我知道我需要在items的click事件中添加一些内容。可以设置一个带有标签索引号的变量,也许......?

另外,如何在输入代码时获得自动建议。例如,我希望能够键入CustomListBox1.itemCollection.add(“Text”,imageSrc)...等我除了查看大量自定义控件之外我不知道要输入什么内容,直到我找到一个包含此

修改

我查看了this自定义列表框。

我尝试将MouseMove事件添加到每个项目中,因此认为它就像放置它一样简单:

Private Sub HoverItem(ByVal item As ColorListboxItem, ByVal e As MouseEventArgs)
    msgbox(1)
End Sub

...在“Methods”区域然后

 AddHandler .mousemove, AddressOf HoverItem

到“OnDrawItem”子。对我来说不幸的是,显然并不像msgbox那样简单。 任何有这种控制经验的人都可以对它的工作方式有所了解。也许是MouseMove事件的一个例子,那么我将了解如何添加更多事件(Mouseleave,DblClick ...等)

2 个答案:

答案 0 :(得分:0)

@JoshMason所说的大部分是正确的,但是如果你坚持这样做,那么你不仅需要为你的项目建立一个索引的集合/数组,而且还需要一个链接的相关集合/数组用于相应的图像。

这样你就可以访问项目/图像的索引(当然是正确曝光),这样你就可以为它分配一个图像,就像你将文本分配给项目(索引)一样,你需要确保用于删除项目的代码帐户也会删除相应的图像,但如果您正确链接它们,则应自动执行。

编辑:如需灵感,请快速查看this

答案 1 :(得分:0)

看起来很熟悉 - 我有一些与房子非常类似的东西并跟踪一堆缩略图。一些东西。它的编写方式更多的是ListBox助手而不是自定义控件。这没有什么不对,但是如果你想让它出现在工具箱中并且更可重用,那么考虑重新加工它:

Public Class CustomListBox
    Inherits Panel           ' or maybe Component, depending....

您编写的方式是,您正在尝试通过维护标签和picbox和面板的集合来模拟ListBox功能。如果你开始考虑每个面板+ picbox +文本框作为其OWN整体事物(控件),你可以内化该级别的一些功能(例如事件处理)并保留ListBox帮助器主要用于管理与用户的交互或app(或消失)。我不认为自动建议会发挥作用,直到它成为一个实际的控件或组件。

 Private WithEvents mLbl As TextBox   ' just recently decided to allow text edits
 Private WithEvents mPic As PictureBox

 Public Sub New(ByVal uniqueName As String)
    mLbl = New TextBox
    mPic = New PictureBox

    Name = uniqueName
    .... set required lbl/txt properties

    MyBase.Controls.Add(mLbl)   ' we inherit from Panel
    .... set pic controls    
    MyBase.Controls.Add(mPic)
    ...
    ...

   ' no need for AddHandler, each Item comes with its own built in event
   Private Sub mPic_DClick(ByVal sender As Object, ByVal e As System.EventArgs) _
        Handles mPic.DoubleClick, mLbl.DoubleClick

     IsSelected = Not _IsSelected

   End Sub

使用默认或基本道具创建后,创建它的类会在滚动面板上设置文本,图像和位置等唯一属性,然后再将其添加到滚动面板:

   frmMain.pnlImgList.Controls.Add(newImgItem)

IsSelected(上面)是一个属性,当它从False变为True时,我引发一个新事件ItemSelected以通知每个“ImgItem”控件的app / panel外壳。该应用程序无需知道是否是文本框或pic被点击,因为ImgItem将处理(如编辑文本)。在你的情况下,这可能是在选择/聚焦等时改变颜色(将其分解为2件最终会让你摆脱创建所有新项目的大程序)。

我没有的是这些的任何内部集合。它们被添加到表单上的面板中,该面板的控件集合用于此目的。当这些东西中的新东西被添加到表单中时,它必须使用AddHandler连接到事件,以处理像ItemSelected这样的事件(有一个ControlAdded / ControlRemoved事件,它可以将这些事件挂钩/取消选中事件处理程序!)

您可以使用滚动的项目面板执行类似的操作,这些项​​目的外观和行为类似于列表框。

在您可以执行更改图像之类的操作之前,您需要一个唯一的标识符,以便您知道要更改的图片。看起来您使用文本作为名称。根据您的使用方式,这可能有效,但如果用户可以编辑文本,则可以创建副本;如果名称发生变化,您就有可能失去对事物的追踪。因此,请考虑使用您不会向用户公开的唯一名称标记它们:

' this would be passed to Sub New when creating a new Item
newName = System.Guid.NewGuid.ToString()

唯一ID(名称)是ItemSelected事件中事件args的一部分,可以轻松找到表单上的每个控件:

 ThisCtl = pnlItems.Controls(sender.Name)

要更改图像,只需在“项目”级别公开它:

 Friend Property Pic() As Bitmap
    Get
        ' I dont recall why this is this way, maybe an artifact
        ' from trying different things.
        Return CType(mPic.BackgroundImage, Bitmap)
    End Get

然后表单或帮助者可以更改图像:

 ThisCtl = pnlItems.Controls(sender.Name)      
 ThisCtl.Pic = newImage

frmName.pnlItems(sender.Name).Pic = newImage

重新编辑:您可以通过在鼠标事件中更改BackColor,以便宜的方式完成您想要使用鼠标做的一些事情(更改颜色)。通过使其成为适当的组件可以更好地处理某些事情,以便您可以根据需要使用Shadow和OVerride鼠标和绘制过程。如果将项目保存在实际的ListBOx中,您几乎肯定必须挂钩到DrawItem绘制事件。在决定是否将其转换为组件后,请担心。

HTH