1

パネル内のすべてのコントロールを実行して、各コントロールに対してユーザーが変更したプロパティを見つけようとしています。

だから私はこのコードを持っています:

    Private Sub WriteProperties(ByVal cntrl As Control)

    Try
        Dim oType As Type = cntrl.GetType

        'Create a new control the same type as cntrl to use it as the default control                      
        Dim newCnt As New Control
        newCnt = Activator.CreateInstance(oType)

        For Each prop As PropertyInfo In newCnt.GetType().GetProperties
            Dim val = cntrl.GetType().GetProperty(prop.Name).GetValue(cntrl, Nothing)
            Dim defVal = newCnt.GetType().GetProperty(prop.Name).GetValue(newCnt, Nothing)

            If val.Equals(defVal) = False Then
               'So if something is different....
            End If

        Next
    Catch ex As Exception
        MsgBox("WriteProperties : " &  ex.Message)
    End Try
End Sub

今、私は3つの問題に直面しています:

  1. プロパティが画像 (BackGround Image) を参照すると、エラーが発生します: ImageObject 参照がオブジェクトのインスタンスに設定されていません。

  2. 2 番目の問題は、コード:

     If val.Equals(defVal) = False Then
               'So if something is different....
     End If
    

    val と defVal が同じ場合に実行されることがあります。これは、プロパティが FlatAppearance (より多くの子プロパティを持つ) のような「parentProperty」である場合に発生します。

  3. 私のループは、必要なサイズや場所などの基本的なプロパティを調べません

4

1 に答える 1

1

Re:、次Not set to an instance of an objectのようなことをします...

If val IsNot Nothing AndAlso defVal IsNot Nothing AndAlso Not val.Equals(defVal) Then

どちらの値もNothing(別名Null)でない場合にのみ比較を行います。

残念ながら、#2は根本的な問題.Equalsです。デフォルトでは、2つのオブジェクト参照がメモリ内の同じオブジェクトを指しているかどうかをチェックします。

Dim A As New SomeClass
Dim B As New SomeClass

If A.Equals(B) Then
    ...
End If

多くのクラスにはないオーバーライドされた等式比較器がFalseない限り、戻ります。SomeClass

問題の値が、比較できることがわかっているタイプ(整数、文字列、倍精度浮動小数点数など)であるかどうかを確認できます。そうでない場合は、そのプロパティを繰り返し処理して、同じチェックを再度実行できます。これにより、任意のタイプのパブリックプロパティを比較して同等性を確認できますが、クラスの内部状態が同じであるとは限りません。

(未テスト/疑似)のようなもの..。

Function Compare (PropA, PropB) As Boolean
    Dim Match = True
    If PropA.Value Is Nothing Or PropB.Value Is Nothing
       Match = False
    Else
       If PropA.Value.GetType.IsAssignableFrom(GetType(String)) Or
          PropA.Value.GetType.IsAssignableFrom(GetType(Integer)) Or ... Then
           Match = PropB.Value.Equals(PropB.Value)
       Else
           For Each Prop In PropA.Value.GetType.GetProperties()
               Match =  Compare(Prop, PropB.Value.GetType.GetProperty(Prop.Name))
               If Not Match Then Exit For
           Next
        End If    
    End If    
    Return Match
End Function

値の内部状態が異なる可能性があるため、これはまだ理想的ではありません。

于 2012-10-23T12:54:01.967 に答える