0

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

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

我知道我需要在项目的点击事件中添加一些东西。可能用标签的索引号设置一个变量,也许......?

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

编辑

我研究了这个自定义列表框。

我试图为每个项目添加一个 MouseMove 事件,所以认为它就像放置这个一样简单:

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

...在“方法”区域,然后

 AddHandler .mousemove, AddressOf HoverItem

到“OnDrawItem”子。对我来说不幸的是,这显然不像没有 msgbox 显示的那么容易。任何对此控件有经验的人都可以就其工作原理提供一些见解。也许是 MouseMove 事件的一个例子,所以我会了解如何添加更多事件(Mouseleave,DblClick ......等)

4

2 回答 2

0

这看起来很熟悉——我有一些与房子和跟踪一堆缩略图非常相似的东西。一些东西。它的编写方式更像是一个 ListBox 助手而不是自定义控件。这并没有什么问题,但是如果您希望它显示在工具箱中并且更可重用,请考虑对其进行改造:

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

按照您的编写方式,您试图通过维护标签、picbox 和面板的集合来模拟 ListBox 功能。如果您开始将每个面板+图片框+文本框视为其自身的整体事物(控件),您可以在该级别内化一些功能(例如事件处理),并将 ListBox 帮助器主要用于管理与用户的交互或应用程序(或离开)。我认为自动建议在成为实际控件或组件之前不会起作用。

 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”控件的应用程序/面板。该应用程序不需要知道是文本框还是点击了图片,因为 ImgItem 将处理它(如编辑文本)。在您的情况下,这可能会在选择/聚焦等时改变颜色。(将其分解为两部分最终会让您摆脱创建所有新项目的大过程)。

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

您可以使用看起来和行为类似于列表框的项目滚动面板来执行类似的操作。

在您执行更改图像之类的操作之前,您需要一个唯一标识符,以便您知道要更改哪个图片。看起来您使用文本作为名称。根据您使用它的方式,这可能会起作用,但如果用户可以编辑文本,他们可以创建一个副本;如果名称更改,您将面临丢失跟踪的风险。因此,请考虑使用您自己不向用户公开的唯一名称标记它们:

' 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,您可以用便宜的方式完成一些您想用鼠标执行的操作(更改颜色)。但是,通过将其设置为适当的组件可能会更好地处理某些事情,以便您可以根据需要阴影和覆盖鼠标和绘制程序。如果您将项目保存在实际的 ListBOx 中,则几乎可以肯定您将不得不挂钩到 DrawItem 绘制事件。在决定是否将其转换为组件后,请担心这一点。

高温高压

于 2013-10-12T13:48:24.293 回答
0

@JoshMason 所说的在大多数情况下是正确的,但是如果您坚持这样做,那么您不仅需要为您的项目提供索引的集合/数组,还需要为相应的图像链接关联的集合/数组。

这样您就可以访问项目/图像的索引(当然要正确公开),这样您就可以像为项目(索引)分配文本一样为其分配图像,并且您需要确保您的代码帐户删除一个项目也会删除相应的图像,但如果你正确链接它们,那应该会自动发生。

编辑:为了获得灵感,快速浏览一下。

于 2013-10-12T01:44:48.873 回答