0

一種のカスタム リスト ボックスを作成し、各項目に画像を追加する機能を含めました。これらの画像を 1 つずつ自由に変更できるようにしたいのですが、どうすればよいかわかりません。現時点では、すべてのアイテムで希望する画像のみを選択できます。

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

@JoshMasonが言ったことはほとんどの場合正しいですが、それを主張する場合は、アイテムのインデックス付きコレクション/配列だけでなく、対応する画像のリンクされた関連コレクション/配列も必要です。

そうすれば、アイテム/画像のインデックスにアクセスできるようになり(もちろん適切に公開されます)、テキストをアイテム(インデックス)に割り当てるのと同じように画像を割り当てることができ、コードアカウントを確認する必要がありますfor remove an item は対応する画像も削除しますが、それらを適切にリンクすると、自動的に削除されます。

編集:インスピレーションを得るために、これを簡単に見てみましょう。

于 2013-10-12T01:44:48.873 に答える
0

それは見覚えがあります - 私は家に非常によく似たものを持っており、たくさんのサムネイルを追跡しています。いくつかのこと。記述方法は、カスタム コントロールというよりは ListBox ヘルパーに近いものです。これには何の問題もありませんが、ツールボックスに表示して再利用しやすくしたい場合は、再加工することを検討してください。

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

あなたの書き方では、ラベルと picbox とパネルのコレクションを維持することで ListBox 機能をエミュレートしようとしています。各パネル + picbox + テキストボックスを独自の不可欠なもの (コントロール) として考え始めると、そのレベルの機能の一部 (たとえば、イベント処理) を内部化し、主にユーザーとの対話を管理するために 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 がそれを処理するため (テキストの編集など)、アプリはそれがクリックされたのがテキスト ボックスか pic かを知る必要はありません。あなたの場合、これは選択/フォーカスされたときに色を変更する可能性があります(2つの部分に分割すると、最終的にすべての新しいアイテムを作成するための大きな手順を取り除くことができます)。

私が持っていないのは、これらの内部コレクションです。それらはフォーム上のパネルに追加され、そのパネルのコントロール コレクションがその目的を果たします。これらの新しいものがフォームに追加された場合、ItemSelected などのイベントを処理するために AddHandler を使用してイベントに接続する必要があります (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

あなたの編集について:マウスでやりたいこと(色の変更)のいくつかは、マウスイベントでBackColorを変更することで安価に実行できる場合があります。ただし、必要に応じてマウスとペイントのプロシージャをシャドウおよびオーバーライドできるように、適切なコンポーネントにすることで処理が改善される場合もあります。項目を実際の ListBOX に保持する場合、ほとんどの場合、DrawItem ペイント イベントにフックする必要があります。それをコンポーネントに変換するかどうかを決定した後、それについて心配してください。

HTH

于 2013-10-12T13:48:24.293 に答える