1

I am trying to run through all the controls in a panel and find which properties the user has changed for each control.

So I have this code:

    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

Now I face three problems:

  1. When the property refers to image (BackGround Image) I have an error : ImageObject reference not set to an instance of an object.

  2. The second problem is that the code:

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

    is executes sometimes when the val and defVal are the same. This is happening in cases that the property is a "parentProperty" like FlatAppearance (which has more child properties)

  3. My loop doesn't look into basic properties like Size, or Location which I want

Oded
  • 489,969
  • 99
  • 883
  • 1,009
Nianios
  • 1,391
  • 3
  • 20
  • 45
  • 1
    Re: "Not set to an instance of an object", do something like ... `If val IsNot Nothing AndAlso defVal IsNot Nothing AndAlso Not val.Equals(defVal) Then`. Which will only do the comparison if neither value is `Nothing` aka `Null`. You may actually find it easier to make a note of what's changed as it is changed through the use of `OnChange` events and similar – Basic Oct 23 '12 at 12:34
  • Problem 3 is problem in my code (not in this function so I solved it) – Nianios Oct 23 '12 at 12:42
  • I get an error Ambiguous match found for property Padding when I test a TabControl (the tabControl has two TabPages) Do you know why and how can I overpass it? – Nianios Oct 23 '12 at 13:09
  • The error with Ambiguous Match solved : – Nianios Oct 23 '12 at 15:36
  • If my answer solved your problem, please accept it using the tick on the Left hand side. If you need more assistance, please ask. If you'd prefer to wait for other answer, not a problem at all. – Basic Oct 23 '12 at 23:41

1 Answers1

1

Re: Not set to an instance of an object, do something like ...

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

Which will only do the comparison if neither value is Nothing (aka Null).

Unfortunately, #2 is a fundamental problem - .Equals by default checks if the 2 object references point at the same object in memory - eg if You did

Dim A As New SomeClass
Dim B As New SomeClass

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

Would return False unless SomeClass has an overridden equality comparer, which many classes do not.

You could check if the value in question is a type you know you can compare (Integer, String, Double, etc). If not, you could iterate through its properties and perform the same check again. This would allow you to compare the public properties of any type for equality but wouldn't guarantee the internal state of the classes is the same.

Something Like (Untested/Pseudo)...

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

This is still not ideal as the internal states of the values may differ.

Basic
  • 26,321
  • 24
  • 115
  • 201