我正在为许多自定义控件开发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值作为布尔等...)。
我做错了什么?
答案 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拆分操作。