我有一个System.Windows.Forms.Listbox,它通过包装类传递,包装类似乎保留在items集合上。在实际清除项目之前,我必须先调用lstBox.Items.Clear两次。使用items.add方法添加项目,因此不使用数据源绑定。
这是基本的代码结构:
我有一个名为WrapListBox的类,它继承了System.Windows.Forms.Listbox。 WrapListBox重写OnDrawItem,OnMeasureItem,OnResize方法,因此包装器。
我的对象在其初始化方法中创建了一个新的WrapListBox实例,并通过标准属性传递给WrapListBox(表单上的一个Listbox)。
所以代码片段看起来像这样:
m_WorkItem = New WorkItem
m_WorkItem.PreviewMessages = lvwMessages
lvwMessages是表单上的ListBox。 m_WorkItem.PreviewMessages将ListBox传递给成员变量m_log。
Public Property PreviewMessages() As WrapListBox
Get
Return m_log
End Get
Set(ByVal Value As WrapListBox)
m_log = Value
End Set
End Property
然后我有另一个包装类WrapListBoxLogger,它传递m_log对象并处理向列表框添加项目。 m_log被传递给WrapListBoxLogger的New构造函数,它将m_log对象传递给另一个成员变量mlstDestination,它是WrapListBox类型。
Public Sub New(ByVal lstDestination As WrapListBox)
mlstDestination = lstDestination
End Sub
如果我调用m_log.items.clear,则item集合不会更改。如果我再次调用m_log.items.clear,则清除项目。我已经尝试创建事件并在包含原始列表框的表单上处理它们,我尝试在链中的各个点调用clear方法,但在第二次清除调用之前仍然没有清除任何内容。 / p>
我只能想象那里有一些挥之不去的参考对象阻止它被清除,但我无法弄清楚它是什么。我希望有人可以帮我确定解决方案吗?
如果您已经了解此行,感谢您花时间阅读。如果您对代码结构有任何疑问,请询问。
编辑: 公共类WrapListBox 继承System.Windows.Forms.ListBox
Private Shared ReadOnly STRING_FORMAT As StringFormat = CreateStringFormat()
Private Shared Function CreateStringFormat() As StringFormat
Dim sf As New StringFormat(StringFormat.GenericTypographic)
sf.Trimming = StringTrimming.EllipsisWord
Return sf
End Function
Protected Const MARGIN_OUTER As Integer = 2
Protected Const MARGIN_INNER As Integer = 4
Protected Const ICON_WIDTH As Integer = 20
Private mobjImageList As ImageList
Public Sub New()
MyBase.New()
Me.DrawMode = Windows.Forms.DrawMode.OwnerDrawVariable
Me.IntegralHeight = False
Me.UseTabStops = True
Me.ResizeRedraw = True
End Sub
Public Property ImageList() As ImageList
Get
Return mobjImageList
End Get
Set(ByVal Value As ImageList)
mobjImageList = Value
End Set
End Property
Protected Overrides Sub OnDrawItem(ByVal e As System.Windows.Forms.DrawItemEventArgs)
If Me.DesignMode Then Exit Sub
'Debug.WriteLine("OnDrawItem " & e.Index & " : " & e.Bounds.ToString)
If e.Index > -1 AndAlso e.Index < Me.Items.Count Then
Dim objItem As WrapListBoxItem = DirectCast(Me.Items(e.Index), WrapListBoxItem)
Dim objBrush As New SolidBrush(e.ForeColor)
Dim objPen As New Pen(e.ForeColor)
Dim objGraphics As Graphics = e.Graphics
objGraphics.Clip = New Region(e.Bounds)
' draw background
objBrush.Color = Me.BackColor
objGraphics.FillRectangle(objBrush, e.Bounds)
e.DrawFocusRectangle()
' draw border
Dim rectBorder As Rectangle = e.Bounds
rectBorder.X += MARGIN_OUTER
rectBorder.Y += MARGIN_OUTER
rectBorder.Height -= MARGIN_OUTER * 2
rectBorder.Width -= MARGIN_OUTER * 2
If CBool(e.State And DrawItemState.Selected) Then
objPen.Color = SystemColors.Highlight
objPen.Width = 2
Else
objPen.Color = SystemColors.Control
objPen.Width = 1
End If
objGraphics.DrawRectangle(objPen, rectBorder)
' size caption area
Dim rectCaption As New RectangleF(rectBorder.X, rectBorder.Y, rectBorder.Width, rectBorder.Height)
rectCaption.X += MARGIN_INNER
rectCaption.Y += MARGIN_INNER
rectCaption.Height -= MARGIN_INNER * 2
rectCaption.Width -= MARGIN_INNER * 2
' draw icon
If Not mobjImageList Is Nothing AndAlso objItem.ImageIndex > -1 Then
Dim objImage As Image = mobjImageList.Images(objItem.ImageIndex)
objGraphics.DrawImage(objImage, rectCaption.X, rectCaption.Y)
rectCaption.X += ICON_WIDTH
rectCaption.Width -= ICON_WIDTH
End If
' draw caption
objBrush.Color = Me.ForeColor
objGraphics.DrawString(objItem.Text, e.Font, objBrush, rectCaption, STRING_FORMAT)
objBrush.Dispose()
objPen.Dispose()
End If
End Sub
Protected Overrides Sub OnMeasureItem(ByVal e As System.Windows.Forms.MeasureItemEventArgs)
If Me.DesignMode Then Exit Sub
If e.Index > -1 AndAlso e.Index < Me.Items.Count Then
Dim objItem As WrapListBoxItem = DirectCast(Me.Items(e.Index), WrapListBoxItem)
Dim sngWidth As Single = Me.Width - ((MARGIN_OUTER * 2) + (MARGIN_INNER * 2))
If Not mobjImageList Is Nothing AndAlso objItem.ImageIndex > -1 Then
sngWidth -= ICON_WIDTH
End If
Dim areaSize As SizeF = New SizeF(sngWidth, 100)
'Limit the length of the text to measure otherwise you get a generic GDI+ error
If Not String.IsNullOrEmpty(objItem.Text) AndAlso objItem.Text.Length > 10000 Then
objItem.Text = objItem.Text.Substring(0, 10000)
End If
Dim textSize As SizeF = e.Graphics.MeasureString(objItem.Text, Me.Font, areaSize)
e.ItemHeight = CInt(textSize.Height) + (MARGIN_OUTER * 2) + (MARGIN_INNER * 2)
e.ItemWidth = Me.Width
'Debug.WriteLine("OnMeasureItem (" & e.ItemWidth.ToString & "," & e.ItemHeight.ToString & ")")
End If
End Sub
Protected Overrides Sub OnResize(ByVal e As System.EventArgs)
MyBase.OnResize(e)
Me.BeginUpdate()
Me.RefreshItems()
Me.EndUpdate()
End Sub
Private Sub InitializeComponent()
Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(WrapListBox))
Me.SuspendLayout()
'
'WrapListBox
'
resources.ApplyResources(Me, "$this")
Me.ResumeLayout(False)
End Sub
Public Class WrapListBoxItem
Private m_imageIndex As Integer = -1
Private m_text As String = String.Empty
Private m_tag As Object = Nothing
Public Sub New(ByVal strText As String)
m_text = strText
End Sub
Public Sub New(ByVal strText As String, ByVal intImage As Integer)
m_text = strText
m_imageIndex = intImage
End Sub
Public Property ImageIndex() As Integer
Get
Return m_imageIndex
End Get
Set(ByVal value As Integer)
m_imageIndex = value
End Set
End Property
Public Property Text() As String
Get
Return m_text
End Get
Set(ByVal value As String)
m_text = value
End Set
End Property
Public Property Tag() As Object
Get
Return m_tag
End Get
Set(ByVal value As Object)
m_tag = value
End Set
End Property
End Class
结束班