Differencebetween Property and Dependency Property

What is the difference between Property and Dependency Property

Dependency property is a property (not itself, but dependent on another, let’s say a XAML Binding property) which register another property.

The dependecy property register the other binding property in the code behind by registering it. A example that is used in my project is as follows:

public static DependencyProperty ImageUri = DependencyProperty.Register("Source", typeof(BitmapImage), typeof(CustomImagePlaceHolder), new PropertyMetadata(null));

In the above code the ImageUri, is a dependency property which register the Source, that is defined/declared inside generic.xaml (whatever not sure whether declared, defined or anything else) as follows:

..HorizontalAlignment="Center"
VerticalAlignment="Center"
Height="{TemplateBinding Height}"
Width="{TemplateBinding Width}"
/>

So here it is quite important that the template binding value in the XAML should be registered as dependency property in the code behind.

So when we have defined in XAML that the Image Source should be template bind with Source, we have registered the same Source
As a DependencyProperty.

We have to say which type of dependency property is that, in above example the Source is the type of BitmapImage, so we have defined typeof(BitmapImage).

Now the owner/parent of this dependency property is our customControlClass CustomImagePlaceHolder, and we have defined that again while registering.

Now to set the value of depndency property, by using our properties as below:

public BitmapImage Source
{
get
{

string strURI = (string)GetValue(CustomImagePlaceHolder.ImageUri);
return new BitmapImage(new Uri(strURI));
}
set
{
SetValue(CustomImagePlaceHolder.ImageUri, value);
}

}

Now this is how it go, we set the value from our code behind or xaml to the source property defined above, and inturn it sets the value of the dependecy property ImageUri, which inturn sets the value in the template binding Source, as we have registered ImageUri as Source, that is presennt generic.xaml.

What's the difference between a dependency property and an attached property in WPF?

Abstract

Since I found little to no documentation on the matter, it took some poking around the source code, but here's an answer.

There is a difference between registering a dependency property as a regular and as an attached property, other than a "philosophical" one (regular properties are intended to be used by the declaring type and its deriving types, attached properties are intended to be used as extensions on arbitrary DependencyObject instances). "Philosophical", because, as @MarqueIV noticed in his comment to @ReedCopsey's answer, regular properties can also be used with arbitrary DependencyObject instances.

Moreover, I have to disagree with other answers stating that attached property is "type of dependency property", because it's misleading - there aren't any "types" of dependency properties. The framework doesn't care if the property was registered as attached or not - it's not even possible to determine (in the sense that this information is not recorded, because it's irrelevant). In fact, all properties are registered as if they were attached properties, but in case of regular ones some additional things are done that slightly modify their behavior.

Code excerpt

To save you the trouble of going through the source code yourself, here's a boiled down version of what happens.

When registering a property without metadata specified, calling

DependencyProperty.Register(
name: "MyProperty",
propertyType: typeof(object),
ownerType: typeof(MyClass))

yields exactly the same result as calling

DependencyProperty.RegisterAttached(
name: "MyProperty",
propertyType: typeof(object),
ownerType: typeof(MyClass))

However, when specifying metadata, calling

DependencyProperty.Register(
name: "MyProperty",
propertyType: typeof(object),
ownerType: typeof(MyClass),
typeMetadata: new FrameworkPropertyMetadata
{
CoerceValueCallback = CoerceCallback,
DefaultValue = "default value",
PropertyChangedCallback = ChangedCallback
});

is equivalent to calling

var property = DependencyProperty.RegisterAttached(
name: "MyProperty",
propertyType: typeof(object),
ownerType: typeof(MyClass),
defaultMetadata: new PropertyMetadata
{
DefaultValue = "default value",
});
property.OverrideMetadata(
forType: typeof(MyClass),
typeMetadata: new FrameworkPropertyMetadata
{
CoerceValueCallback = CoerceCallback,
DefaultValue = "default value",
PropertyChangedCallback = ChangedCallback
});

Conclusions

The key (and only) difference between regular and attached dependency properties is the default metadata available through DependencyProperty.DefaultMetadata property. This is even mentioned in the Remarks section:

For nonattached properties, the metadata type returned by this property cannot be cast to derived types of PropertyMetadata type, even if the property was originally registered with a derived metadata type. If you want the originally registered metadata including its original possibly derived metadata type, call GetMetadata(Type) instead, passing the original registering type as a parameter.

For attached properties, the type of the metadata returned by this property will match the type given in the original RegisterAttached registration method.

This is clearly visible in the provided code. Little hints are also hidden in the registering methods, i.e. for RegisterAttached the metadata parameter is named defaultMetadata, whereas for Register it is named typeMetadata. For attached properties the provided metadata becomes the default metadata. In case of regular properties however, the default metadata is always a fresh instance of PropertyMetadata with only DefaultValue set (either from provided metadata or automatically). Only the subsequent call to OverrideMetadata actually uses the provided metadata.

Consequences

The main practical difference is that in case of regular properties the CoerceValueCallback and PropertyChangedCallback are applicable only for types derived from the type declared as the owner type, and for attached properties they're applicable for all types. E.g. in this scenario:

var d = new DependencyObject();
d.SetValue(SomeClass.SomeProperty, "some value");

the registered PropertyChangedCallback will be called if the property was registered as an attached property, but will not be called if it was registered as a regular property. Same goes to CoerceValueCallback.

A secondary difference stems from the fact that OverrideMetadata requires that supplied type derives from DependencyObject. In practice it means that the owner type for regular properties must derive from DependencyObject, whereas for attached properties in can be any type (including static classes, structs, enums, delegates, etc.).

Supplement

Besides @MarqueIV's suggestion, on several occasions I've come across opinions that regular and attached properties differ in the way they can be used in XAML. Namely, that regular properties require implicit name syntax as opposed to explicit name syntax required by attached properties. This is technically not true, although in practice it usually is the case. For clarity:

<!-- Implicit property name -->
<ns:SomeClass SomeProperty="some value" />

<!-- Explicit property name -->
<DependencyObject ns:SomeClass.SomeProperty="some value" />

In pure XAML, the only rules governing the usage of these syntaxes are the following:

  • Implicit name syntax can be used on an element if and only if the class that this element represents has a CLR property of that name
  • Explicit name syntax can be used on an element if and only if the class specified by the first part of the full name exposes appropriate static get/set methods (referred to as accessors) with names matching the second part of the full name

Satisfying these conditions enables you to use corresponding syntax regardless of whether the backing dependency property was registered as regular or attached.

Now the mentioned misconception is caused by the fact that vast majority of tutorials (together with stock Visual Studio code snippets) instruct you to use CLR property for regular dependency properties, and get/set accessors for attached ones. But there's nothing stopping you from using both at the same time, allowing you to use whichever syntax you prefer.

Difference between dependency properties in WPF

You can bind to the DependencyProperty some value which can implement INotifyPropertyChanged. For example, if you write:

<TextBox Content="{Binding FirstName}" />

then Content is a dependency property which will react to the binding source changing.

The main difference is, that the value of a normal .NET property is
read directly from a private member in your class, whereas the value
of a DependencyProperty is resolved dynamically when calling the
GetValue() method that is inherited from DependencyObject.

When you set a value of a dependency property it is not stored in a
field of your object, but in a dictionary of keys and values provided
by the base class DependencyObject. The key of an entry is the name of
the property and the value is the value you want to set.

via

You should use simple properties in your ViewModels which you'll bind to the dependency properties in WPF objects (Content, Background, IsChecked and many other include DP which you will define in your custom user controls).

XAML Dependency Property vs Regular Properties

The main reason to use dependency properties is to allow the underlying subsystem to provide additional UI/XAML/WPF based functionality, namely:

1) Binding.
In this code:

<Slider x:Name="slid1" Maximum="5280" Minimum="16" Value="250" />
<Boards:BoardCalc x:Name="boardCalc1"
LengthRequired="{Binding ElementName=slid1,Path=Value" />

LengthRequired must be a dependency property. You can set LengthRequired like this

LengthRequired = "5280"

and you can do this

Text={Binding ElementName=boardCalc1, Path=LengthRequired} ...

but you can't SET LengthRequired using the Binding extension.

2) Animation
3) Styling

Same basic principle. To allow the underlying UI subsystem to animate from 0 to 100 or whatever, or to get the subsystem to pick up Styling and Themes and whatever, it must be a dependency property.

1,2,3. Reasons to use dependency property.
For regular properties you can jam in an INotify.

INotifyPropertyChanged vs. DependencyProperty in ViewModel

Kent wrote an interesting blog about this topic: View Models: POCOs versus DependencyObjects.

Short summary:

  1. DependencyObjects are not marked as
    serializable
  2. The DependencyObject class overrides and seals the Equals() and
    GetHashCode() methods
  3. A DependencyObject has thread affinity – it can only be accessed
    on the thread on which it was
    created

I prefer the POCO approach. A base class for PresentationModel (aka ViewModel) which implements INotifyPropertyChanged interface can be found here: http://compositeextensions.codeplex.com

Is dependency property same as a CLR property which emits a PropertyChanged event as callback?

An dependency property is on a DependencyObject from which all WPF UI elements derive from (and only works there), as it's static and saves it's value in a kind of collection assigned to a specific DependencyObject (on which the dependency property is defined). Dependency properties can be defined in a class outside of the actual DependencyObject to extend it's functionality without modifying the original user control class.

When you write a user control and want a ViewModel to allow to bind a value and receive notifications when it's changed, then you create a dependency property.

Imagine it like an USB cable, where you have a male plug and a female receptacle. The CLR property is like the plug and the dependency property is like the receptacle.

A dependency property allows you to store that's associated with a control but isn't part of the instance. As you can see on the MSDN Examples

public static readonly DependencyProperty IsSpinningProperty = 
DependencyProperty.Register(
"IsSpinning", typeof(Boolean),

...

);
public bool IsSpinning
{
get { return (bool)GetValue(IsSpinningProperty); }
set { SetValue(IsSpinningProperty, value); }
}

the dependency property is static and GetValue and SetValue are methods of DependencyObject (base class on which all WPF UI elements are based on).

Depencency Properties (and attached properties/attached behavior) can also be used to extend the functionality of a UserControl without inheriting from the actual user control type, i.e. notifying the ViewModel when a certain value changes which is not provided by the original user control.

  1. Is the Dependency Property same as CLR property which emits a PropertyChanged event when it changes?

No, it's not the same. They are both 2 sides of the databinding engine. A DP is defined on the view to allow a view model to bind a INPC Property (Property that rises PropertyChanged event)


  1. Whether Dependency property is written in the view itself(MyPage.xaml.cs) or can it be included in the view model(MyPageViewModel.cs)?

DP are part of the View-Layer as they depend on DependencyObject, which is part of the WPF framework and hence view concern. While technically nothing prevents you from using them in the ViewModel, this causes a tight coupling of your ViewModel towards a certain View technology, so it doesn't fully comply MVVM pattern.

Be aware though that unit testing Dependency Properties may be quite difficult as they don't store the values on the class they are defined on but in some kind of dictionary where the GetValue/SetValue methods warp around.

Last but not least, since DependencyObject is the base class of all UI it is as well as most of the classes that derive from it thread affine, which means you can only access it from the thread you created which may cause you much pain in both unit test (especially if the tests run in parallel like MSTest used to do. Dunno if its still true as of today) and in your code.


  1. In MVVM pattern, we use the CLR properties more which emits an event during property change. So can dependency property be replaced by such kind of CLR properties?

In ViewModels you could and you should use INotifyPropertyChanged. If you are developing a user control, you shouldn't replace DPs with "CLR" properties, because this makes the property not work with databinding in XAML.

If your UI elements should expose a property which can be used with data binding you have to use dependency properties (or attached properties which are pretty similar, but you place attached properties on i.e. the child elements. Grid.Row and Grid.Column are examples of attached properties).

What is a dependency property?

Dependency properties are properties of classes that derive from DependencyObject, and they're special in that rather than simply using a backing field to store their value, they use some helper methods on DependencyObject.

The nicest thing about them is that they have all the plumbing for data binding built in. If you bind something to them, they'll notify it when they change.

When should I use dependency properties in WPF?

Dependency Property is a broad concept to explain which might take couple of pages to write. So just to answer your main question, Dependency property is used where

  1. You know the property is going to be the binding target i.e you are creating a user control/custom control and want property that should be binding driven.

  2. You want automatic property change notifications (coerse and validation also).

  3. We want value inheritance in styles,themes, parent or default value.

  4. There is not need to create the properties on Model or ViewModel layer as dependency properties most of the time as that is not going to help much on memory saving front as most of the properties we define in model/VM will have values per instance as they will be constantly changing. Resolving Dependency property value is a burden in itself so making property dependency unnecessarily is not advisable.

Thanks



Related Topics



Leave a reply



Submit