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

现在我面临三个问题:

  1. 当属性引用图像(背景图像)时,我有一个错误:ImageObject 引用未设置为对象的实例。

  2. 第二个问题是代码:

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

    is 有时在 val 和 defVal 相同时执行。如果属性是像 FlatAppearance 一样的“parentProperty”(它有更多的子属性),就会发生这种情况

  3. 我的循环没有查看我想要的基本属性,如大小或位置

4

1 回答 1

1

回复: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 回答