2013-10-12 161 views
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 

我知道我需要添加一些东西到items.Possible的Click事件设置与标签的索引号的变量,也许...?

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

编辑

我已经调查this自定义列表框。

,我打算给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等)

+0

这就是'WPF'的原因。没有重新发明轮子和装订已经到位。 – OneFineDay

回答

0

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

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

编辑:为了获得灵感,请给this快速一下。

+0

我现在已经设置了一个变量点击,并得到它只为第一个项目点击工作。我想不出如何对它进行排序,以便每次点击都声明一个新的picbox Dim xg作为新的PictureBox = Me.SelectedItem.Controls.Item(0)' –

+0

不,不这样做。最好的方法是创建一个类文件并引用它,这种编码非常不雅且缓慢。 –

+0

我不明白你的意思。也许举个例子吧。 (我会创建一个新班级,对吧?) –

0

看起来很熟悉 - 我有一些非常相似的房子和跟踪一堆缩略图。一些东西。它被写入的方式多于ListBox帮助程序而不是自定义控件。没有什么错,但如果你希望它在工具箱中显示出来,并会更加重用,考虑返工吧:

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

你写的样子,你试图通过保持效仿列表框的功能标签和picboxes和面板的集合。如果您开始将每个面板+ picbox +文本框视为OWN不可或缺的东西(控制),则可以内部化该层的某些功能(例如事件处理),并让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 

后,它与默认的或基本的道具,那就是创造它添加到scrollpanel之前这台独特的像滚动面板上的文字,图片和位置类创建:

frmMain.pnlImgList.Controls.Add(newImgItem) 

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

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

您可以使用外观和行为类似于列表框的项目的滚动面板来做类似的事情。

在你可以做像改变图像之类的东西之前,你需要一个唯一的标识符,以便你知道哪个图片可以改变。它看起来像你使用文本作为名称。取决于你如何使用它,这可能会工作,但如果用户可以编辑文本,他们可以创建一个副本;如果名称发生变化,您可能会失去跟踪事物的风险。因此,可以考虑用自己的独特的名称心不是暴露给用户标记它们:

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

的唯一ID(名称)是ItemSelected事件的事件参数的个数一部分,因此很容易发现在每个控制形式:

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

回复您的编辑:你们中有些人想用鼠标(改变颜色)做什么可能是能够在廉价通过鼠标事件改变背景色来完成。有些东西虽然可能会更好地通过使其成为适当的组件来处理,以便您可以根据需要使用阴影和OVerride鼠标和绘制过程。如果将这些项目保存在实际的ListBOx中,则几乎肯定必须挂钩DrawItem绘画事件。在您决定是否将其转换为组件后,需要担心这一点。

HTH