Listbox SelectedIndexCollection与SelectedIndices

时间:2017-02-06 16:38:14

标签: vb.net listbox generic-programming undo-redo

我正在为许多自定义控件开发Generic Undoclass,并且在尝试为多选列表框实现撤消时遇到困难。

撤消类:

Public Class UndoClass(Of T)
    Private FirstValue As T
    Private PrevValue As T
    Private CurrentValue As T
    Private HasValue As Boolean
    Public Sub Add(ByVal Item As T)
        If Not HasValue Then
            FirstValue = Item
            PrevValue = Item
            HasValue = True
        ElseIf Not CurrentValue.Equals(Item) Then
            If Not CurrentValue.Equals(FirstValue) Then PrevValue = CurrentValue
        End If
        CurrentValue = Item
    End Sub

和一些撤消代码。在自定义Listbox类中,我添加了:

dim undoing as new UndoClass(Of SelectedIndexCollection)

Protected Overrides Sub OnEnter(e As EventArgs)
    undoing.add(me.SelectedIndices)
    ....
Protected Overrides Sub OnSelectedIndexChanged(e As EventArgs)
    if me.SelectedIndex>=0 then undoing.add(me.selectedIndices)
    ....

我遇到的问题是传递的"项目"没有公开与原始SelectedIndices属性相同的属性,因此CurrentValue.equals(item)测试总是失败。尽管vs helpfile明确指出selectedIndices是一个" ListBox.SelectedIndexCollection,其中包含控件中当前所选项的索引"我这样做的方式不起作用(它适用于我所有的其他控件,我只是将它们的.text值作为字符串传递或.Checked值作为布尔等...)。

我做错了什么?

1 个答案:

答案 0 :(得分:0)

我想我找到了一种方法来解决它(只是一个测试例程,因此我使用函数返回测试信息而不是方法和短变量名称):

Public Class TestListClass(Of T)
    Dim Current As New List(Of T)
    Dim Prev As New List(Of T)
    Public Function add(T1 As List(Of T)) As String
        Dim s As String = String.Empty
        If T1.GetType.IsGenericType Then    ' better safe then sorry and we'll need that in the final version
            Dim ar As Type() = T1.GetType.GenericTypeArguments
            s = ar(0).ToString
        End If
        If Current.Count = 0 Then
            For Each X As T In T1
                Current.Add(X)
            Next
            Return "created " & s & vbNewLine
        Else
            If Prev.Count > 0 Then Prev.Clear()
                For Each X As T In Current
                    Prev.Add(X)
                Next
                Current.Clear()
                For Each X As T In T1
                    Current.Add(X)
                Next
                Return "pushed " & s & vbNewLine
            End If
        End Function
        Public Function Listing() As String
            Dim S As String = String.Empty
            If Prev.Count > 0 Then
                S &= "Prev= " & Enumerate(Prev) & vbNewLine
            End If
            If Current.Count > 0 Then
                S &= "Current= " & Enumerate(Current) & vbNewLine
            End If
            Return S
        End Function
        Private Function Enumerate(T1 As List(Of T)) As String
            Dim s As String = String.Empty
            For I = 0 To T1.Count - 1
                s &= T1.Item(I).ToString & csComa
            Next
            Return s
        End Function
Public Function Compare(T1 As List(Of T)) As String
    Dim s As String = Enumerate(T1)
    If ListsSame(Current, T1) Then
        s &= "is same as current! (" & Enumerate(Current) & ")"
    ElseIf ListsSame(Prev, T1) Then
        s &= "is same as Previous! (" & Enumerate(Prev) & ")"
    Else
        s &= "does not match!"
    End If
    Return s & vbNewLine
End Function
    Private Function ListsSame(T1 As List(Of T), T2 As List(Of T)) As Boolean
        Dim ok As Boolean = False
        If T1.Count > T2.Count Then
            ok = T1.Except(T2).Any
        Else
            ok = T2.Except(T1).Any
        End If
        Return Not ok
    End Function
End Class

我必须遍历'add'例程中的列表,因为相等运算符会创建对当前值的引用而不是复制内容

测试代码:

Dim t1 As New TestListClass(Of Integer), l1 As New List(Of Integer), t2 As New TestListClass(Of String), l2 As New List(Of String)
Dim x1() As Integer = {1, 2, 3, 4, 5}
l1.AddRange(x1)
Me.txtResult.Text = t1.add(l1)
Dim y1() As Integer = {6, 7, 8}
Dim l11 As New List(Of Integer)
l11.AddRange(y1)
Me.txtResult.Text &= t1.add(l11)
Me.txtResult.Text &= t1.Listing
Me.txtResult.Text &= t1.Compare(l1)
Me.txtResult.Text &= t1.Compare(l11)
l11.Add(9)
Me.txtResult.Text &= t1.Compare(l11)
Dim x2() As String = {"10", "20", "30"}
l2.AddRange(x2)
Me.txtResult.Text &= t2.add(l2)
Dim y2() As String = {"a", "b", "c"}
Dim l22 As New List(Of String)
l22.AddRange(y2)
Me.txtResult.Text &= t2.add(l22)
Me.txtResult.Text &= t2.Listing
Me.txtResult.Text &= t2.Compare(l2)
Me.txtResult.Text &= t2.Compare(l22)
l22.Add("d")
Me.txtResult.Text &= t2.Compare(l22)

输出:

created System.Int32
pushed System.Int32
Prev= 1, 2, 3, 4, 5, 
Current= 6, 7, 8, 
1, 2, 3, 4, 5, is same as Previous! (1, 2, 3, 4, 5, )
6, 7, 8, is same as current! (6, 7, 8, )
6, 7, 8, 9, does not match!
created System.String
pushed System.String
Prev= 10, 20, 30, 
Current= a, b, c, 
10, 20, 30, is same as Previous! (10, 20, 30, )
a, b, c, is same as current! (a, b, c, )
a, b, c, d, does not match!

接下来,当selectedItem或SelectedValue作为基本变量传递时,我打算基于gettype.IsgenericType拆分操作。