2013-10-12 82 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