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 установить переменную с порядковым номером на этикетке, может быть ...?

Кроме того, как получить автоматические предложения при вводе кода. Например, я хочу иметь возможность набирать CustomListBox1.itemCollection.add («Текст», imageSrc) ... и т. Д. Я просто понятия не имею, что вводить в Google, кроме как просматривать множество пользовательских элементов управления, пока не найду тот, который включает это.

EDIT

Я посмотрел в this пользовательские ListBox.

Я пытался добавить событие 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 ... и т. Д.)

+0

Это то, что было сделано для WPF. Никакое повторное изобретение колеса и привязок уже на месте. – OneFineDay

ответ

0

Что, по большому счету, то, что сказал @JoshMason, но если вы настаивайте на этом, тогда вам нужны не только индексированные коллекции/массивы для ваших элементов, но также связанные связанные коллекции/массивы для соответствующих изображений.

Таким образом, индекс элемента/изображения будет доступен вам (правильно выставлен, конечно), чтобы вы могли присвоить ему изображение, как если бы вы назначили текст элементу (индексу), и вам нужно сделать убедитесь, что ваши учетные записи кода для удаления элемента также удаляют соответствующее изображение, но если вы правильно их связываете, это должно произойти автоматически.

EDIT: Для вдохновения дайте this быстрый взгляд.

+0

Теперь я установил переменную на клик и заставил ее работать только для первого щелкнутого элемента. Я не могу придумать, как сортировать это так, чтобы он объявлял новый picbox при каждом нажатии 'Dim img. Как новый PictureBox = Me.SelectedItem.Controls.Item (0)' –

+0

Нет, нет, вы этого не делаете , Лучший способ сделать это - создать файл класса и указать его, такой вид кодирования очень неэлегантен и медленный. –

+0

Я не понимаю, что вы имеете в виду.Возможно, приведу пример. (Я создам новый класс, не так ли?) –

0

Это выглядит знакомым - у меня есть что-то очень похожее на дом и отслеживание кучи миниатюр. Несколько вещей. Как это написано, это скорее помощник ListBox, чем пользовательский элемент управления. Там нет ничего плохого, но если вы хотите, чтобы показать в панели инструментов и более многоразовые, считают переработав его:

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

То, как твое написано, вы пытаетесь подражать функциональности ListBox, поддерживая коллекция этикеток и picboxes и панелей. Если вы начинаете думать о каждой панели + picbox + textbox как своей встроенной вещи (управление), вы можете интернализировать некоторые функции на этом уровне (например, обработку событий) и оставить помощника 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, которое делает приятное место для подключения/отцепления их в выбранном обработчик события!)

Вы можете сделать что-то подобное, используя панель прокрутки элементов, которая выглядит и действует как Listbox.

Прежде чем вы сможете делать такие вещи, как изменение изображения, вам нужен уникальный идентификатор, чтобы вы знали, какое изображение нужно изменить. Похоже, вы используете текст в качестве имени. В зависимости от того, как вы его используете, это может сработать, но если пользователь может редактировать текст, он может создать дубликат; и если имя изменится, вы рискуете потерять контроль над вещами. Итак, рассмотрит помечая их с вашим собственным уникальным именем, которое Isnt подвергается воздействию пользователя:

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

Уникальный идентификатор (имя) является частью событий аргументов в случае 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

Re правки: Часть того, что вы хотите сделать с помощью мыши (Изменить цвета) может быть в состоянии сделать на дешевом путем изменения BackColor в событиях мыши. Некоторые вещи, хотя их можно было бы лучше обработать, сделав их подходящими компонентами, чтобы вы могли при необходимости рисовать процедуры Shadow и OVerride по мере необходимости. Если вы сохраняете элементы в реальном ListBOx, вам почти наверняка придется подключаться к событиям рисования DrawItem. Беспокойство об этом после того, как вы решите, преобразовать ли его в компонент.

HTH

Смежные вопросы