2017-02-06 7 views
0

私はいくつかのカスタムコントロールのGeneric Undoclassで作業していて、複数選択リストボックスの取り消しを実装しようとしたときに立ち往生しました。 リストボックス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 

といくつかのコードを元に戻します。カスタムリストボックスクラスで私がコメントを追加しました:

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は、selectedIndicesが "コントロール内の現在選択されている項目のインデックスを含むListBox.SelectedIndexCollection"であることを明確に述べていますが、私のやり方はうまくいきません。ブール値などのように文字列または.Checked値として)。

どうしたのですか?

+0

「SelectedIndices」は読み取り専用のプロパティであるという問題があると思います。 – LarsTech

+0

私が過去に行ったことは、コントロールタイプの元に戻すことではなく、元に戻すことではなく、複数の場合があります。リストコントロールは苦痛です。コレクションのプロパティを完全に設定することはできないので、 'SelectedObjectCollection'をループして各項目のハッシュコードをListに格納することができます。 – 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! 

次に私はのSelectedItemまたはSelectedValueのがベース変数として渡されたときgettype.IsgenericTypeに基づいて操作を分割するつもり。

関連する問題