NoesisGUI

DependencyObject

Introduction

The DependencyObject base class enables derived objects to use the dependency property system.

It also provides the following services and characteristics:

  • Dependency property hosting support. You register a dependency property by calling the RegisterProperty or RegisterPropertyRO (read-only property) method, and storing the created property as a public static field in your class.
  • Attached property hosting support. You register an attached property by calling the RegisterProperty method, and storing the created property as a public static field in your class. Your attached property can then be set on any class that derives from DependencyObject.
  • Get, set, and clear utility methods for values of any dependency properties that exist on the DependencyObject.
  • Metadata, coerce value support, property changed notification, and override callbacks for dependency properties or attached properties. Also, the DependencyObject class facilitates the per-owner property metadata for a dependency property.

It is the common base class for classes derived from Visual, UIElement, or Freezable.

Implementation

Supposing we have a class deriving from DependencyObject:

////////////////////////////////////////////////////////////////////////////////////////////////////
/// A button that raises Click event after a delay time
////////////////////////////////////////////////////////////////////////////////////////////////////
class DelayedButton: public Button
{
    NS_DECLARE_REFLECTION(DelayedButton, Button)
};

Inheritors must take care of some important points about Noesis Engine implementation of the DependencyObject:

  1. DependencyObject is an ISerializable class. It automatically serializes all dependency properties stored locally in the object (default values or inherited values are not serialized). But instance members of derived classes must be serialized manually within their Serialize/Unserialize functions.
void DelayedButton::Serialize(SerializationData* data)
{
    NS_SERIALIZE_PARENT(data);
    data->Serialize(NST("OtherInfo"), mOtherInfo);
}

void DelayedButton::Unserialize(UnserializationData* data, NsUInt32 version)
{
    NS_UNSERIALIZE_PARENT(data);

    if (version == 0)
    {
        data->Unserialize(NST("OtherInfo"), mOtherInfo);
    }
    else
    {
        NS_ERROR(NST("Invalid version"));
    }
}
  1. DependencyObject is an IComponentInitializer class. Before object is initialized, all value modifications are not notified, and expressions are not evaluated (that means that resources and bindings are not resolved). As was the case with serialization, derived classes must initialize instance members that are not dependency properties overriding the OnInit function. Inheritors must call parent implementation to not break dependency object initialization:
void DelayedButton::OnInit()
{
    ParentClass::OnInit();

    InitComponent(mOtherInfo);
}
  1. DependencyObject provides an OnPropertyChanged function to notify inheritors of property changes. Inheritors must call parent implementation to not break the notification system:
NsBool DelayedButton::OnPropertyChanged(const DependencyPropertyChangedEventArgs& e)
{
    NsBool handled = ParentClass::OnPropertyChanged(e);

    if (!handled)
    {
        if (e.prop == DelayProperty)
        {
            // property change management here
            return true;
        }
    }

    return handled;
}

WPF Compatibility

http://msdn.microsoft.com/en-us/library/system.windows.dependencyobject.aspx


Methods:
Name Sup Comments
ClearValue Yes Renamed to ClearLocalValue
CoerceValue Yes  
GetValue Yes  
InvalidateProperty Yes  
ReadLocalValue Yes Renamed to GetLocalValue
SetCurrentValue No  
SetValue Yes  

Properties:
Name Sup Comments
DependencyObjectType No  
IsSealed No  
© 2017 Noesis Technologies