New to Telerik UI for WinFormsStart a free 30-day trial

RadObject

Updated over 6 months ago

RadObject represents a base class for all elements that need to interact with the dependency property system of Telerik Presentation Framework. For instance, RadElement class derives from RadObject so it participates in that system.

The main RadObject functionality is:

MethodDescription
GetValueRetrieves the stored value for a given dependency property.
SetValueSets a value for a given dependency property.
ResetValueResets the value of a given dependency property. There are several reset options specified in ValueResetFlags enumeration.
UpdateValueForces a re-evaluation for a given property.
GetValueSourceIndicates the source of change.
BindPropertyCreates a binding between two properties.
UnbindPropertyDestroys an existing binding between two properties.

Dependency properties are registered using RadProperty class. Refer to this article if you need to create a dependency property but you need not create a custom object that will participate in the hierarchy of visual elements, i.e. custom fill primitive that does not derive from the existing one.

Getting and Setting Values

GetValue and SetValue methods are used for getting and setting local values. Usually you have to define a CLR property for each declared RadProperty whose setter calls GetValue and whose getter calls SetValue:

C#
internal class MyRadObject : RadObject
{
    public static readonly RadProperty HeightProperty =
    RadProperty.Register("Height",
    typeof(int),
    typeof(MyRadObject),
    new RadElementPropertyMetadata(1, ElementPropertyOptions.AffectsArrange | ElementPropertyOptions.AffectsMeasure));
    public int Height
    {
        get
        {
            return (int)this.GetValue(HeightProperty);
        }
        set
        {
            this.SetValue(HeightProperty, value);
        }
    }
}

Resetting Values

If the value is inherited, the inherited value becomes the new value. Otherwise, the value is reset to the default value.

The code snippet below reset the value of the HeightProperty declared in MyRadObject class:

C#
radObject.ResetValue(MyRadObject.HeightProperty);

You can pass a second parameter to the ResetValue method to specify a reset flag:

C#
[Flags]
public enum ValueResetFlags
{
    None = 0,
    Inherited = 1,
    Binding = Inherited << 1,
    TwoWayBindingLocal = Binding << 1,
    Style = TwoWayBindingLocal << 1,
    Animation = Style << 1,
    Local = Animation << 1,
    DefaultValueOverride = Local << 1,
    All = Inherited | Binding | TwoWayBindingLocal | Style | Animation | Local | DefaultValueOverride
}

Updating Values

Re-evaluates the property specified as a parameter. In the example below, the HeightProperty is re-evaluated:

C#
radObject.UpdateValue(MyRadObject.HeightProperty);

Getting Value Source

The value source is the reason for the current value. GetValueSource method returns the ValueSource enumeration which describes the value sources:

C#
public enum ValueSource : short
{
    /// <summary>
    /// Indicates that the reason is unknown.
    /// </summary>
    Unknown = 0,
    /// <summary>
    /// Indicates that the default value is set.
    /// </summary>
    DefaultValue,
    /// <summary>
    /// Indicates that the property changed is inherited.
    /// </summary>
    Inherited,
    /// <summary>
    /// An overriden default value, has higher priority than Default and Inherited source.
    /// </summary>
    DefaultValueOverride,
    /// <summary>
    /// Indicates that the reason for the property change is an applied theme.
    /// </summary>
    Style,
    /// <summary>
    /// Value is set locally through a CLR property setter.
    /// </summary>
    Local,
    /// <summary>
    /// Indicates that the reason for the property change is data binding.
    /// </summary>
    PropertyBinding,
    /// <summary>
    /// A value is applied through two-way binding.
    /// </summary>
    LocalFromBinding,
    /// <summary>
    /// Indicates that the reason for the property change is an animation effect.
    /// </summary>
    Animation,
}

Binding and Unbinding Properties

Properties can be bound to other properties either one-way or two-way. The code snippet below binds two properties one-way:

C#
MyRadObject radObject1 = new MyRadObject();
MyRadObject radObject2 = new MyRadObject();
radObject2.BindProperty(MyRadObject.HeightProperty, radObject1,
MyRadObject.HeightProperty, PropertyBindingOptions.OneWay);

If the binding is one way the source property is the one passed as a parameter to BindProperty method.

Values Precedence

Dependency properties are more advanced than the ordinary properties; they support advance features such as inheritance, and animation. For this reason, precedence rules have to be established. The table below summarizes the precedence rules from highest precedence to lowest:

ValueDescription
CoercionThis is the final step when you can change the value of a given property. Please refer to the subsection below about implementing value coercion.
AnimationWhen the animation is finished, you can either store the last value or remove it and therefore allow previous modifiers to participate in value composition. This behavior is controlled by AnimatedPropertySetting.RemoveAfterApply property. Note: Animation in TPF is controlled by AnimatedPropertySetting object which value has different meanings depending on whether it is specified through StyleSheet or not. If the latter is true, the animation is treated as Style Setting rather than animation.
BindingProperties can be bound either one-way or two way. Refer to the subsection about binding below.
Local ValueThe value that is set through a CLR Property Setter or the publicly exposed SetValue method.
Style SettingA PropertySetting which comes from a StyleSheet.Note: it can be AnimatedPropertySetting which will be treated as a Style rather than Animation.
Inherited ValueValue that comes from the current InheritanceParent for the object. An inherited value is cached once retrieved and stored until caching is marked as Invalid. Note: Only properties, whose metadata object has the IsInherited flag set, are target of inheritance.
Default ValueA default value can be set either using the dependency property metadata or by overriding the method GetDefaultValue . Refer to the subsection below about default values.

Coercion

You need to override CoerceValue method:

C#
protected override object CoerceValue(RadPropertyValue propVal, object baseValue)
{
    if (useCoercion && propVal.Property == MyRadObject.HeightProperty)
    {
        return 105; //coerce value which for the example sake is integer
    }
    return base.CoerceValue(propVal, baseValue);
}

In the example above, the value of the Height property is coerced to 105 (Height is an integer property).

Coercion is seldom used.

Binding

A property of one RadObject instance can be bound to a property of another RadObject instance. There are two binding models:

One wayChange in the source triggers change in the bound target property. The only exception to this case is that animation in progress can change the value of the bound property.
Two waysValue change in one of the properties triggers change in the other.

Local Value

Local values are set and get using SetValue and GetValue methods:

C#
internal class MyRadObject : RadObject
{
    public static readonly RadProperty HeightProperty =
    RadProperty.Register("Height",
    typeof(int),
    typeof(MyRadObject),
    new RadElementPropertyMetadata(1, ElementPropertyOptions.AffectsArrange | ElementPropertyOptions.AffectsMeasure));
    public int Height
    {
        get
        {
            return (int)this.GetValue(HeightProperty);
        }
        set
        {
            this.SetValue(HeightProperty, value);
        }
    }
}

Default Value 

When you define a dependency property, you create a RadElementPropertyMetadata whose first constructor argument is default value:

C#
public static readonly RadProperty HeightProperty =
    RadProperty.Register("Height",
    typeof(int),
    typeof(MyRadObject),
    new RadElementPropertyMetadata(1, ElementPropertyOptions.AffectsArrange | ElementPropertyOptions.AffectsMeasure));

In some rare cases, you might want to override the GetDefaultValue and specify the default value there:

C#
protected override object GetDefaultValue(RadPropertyValue propVal, object baseDefaultValue)
{
    if (propVal.Property == MyRadObject.HeightProperty)
    {
        return 2;
    }
    return base.GetDefaultValue(propVal, baseDefaultValue);
}

See Also