Listbox.Items.Clear不清除项集合

时间:2014-03-25 15:39:27

标签: vb.net winforms listbox

我有一个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的Ne​​w构造函数,它将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

结束班

0 个答案:

没有答案