2017-02-06 6 views
0

Я работаю над универсальным Undoclass для ряда пользовательских элементов управления и застревает при попытке выполнить отмену для многозадачных списков.Listbox SelectedIndexCollection и SelectedIndices

отмененных Класс:

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 (пункт) тест всегда терпит неудачу. Хотя vs helpfile четко заявляет, что выбранныеИндексы представляют собой «ListBox.SelectedIndexCollection, содержащий индексы выбранных в данный момент элементов в элементе управления», как я это делал, он не работает (он работает со всеми моими другими элементами управления, где я просто передаю их значения .text как строки или .Проверенные значения как Boolean и т. д.).

Что я сделал не так?

+0

Я предполагаю, что проблема заключается в том, что 'SelectedIndices' - свойство только для чтения. – LarsTech

+0

То, что я делал в прошлом, основано на Undo на типе управления, а не на том, что отменяется - в некоторых случаях есть несколько вещей, которые нужно посмотреть. Элементы управления списком - это боль - поскольку вы не можете полностью установить свойства набора, вы можете закодировать «SelectedObjectCollection» и сохранить хэш-код каждого элемента в списке. – Plutonix

ответ

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 

мне пришлось перебирать список в «добавить» рутина, как оператор равенства будет создать ссылку на текущее значение вместо копирования содержимого

тестовый код:

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! 

Далее я намерен разделить операции на основе gettype.IsgenericType, когда SelectedItem или SelectedValue передается в качестве базовых переменных.