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

The question is related to WPF Data Binding and MVVM pattern.
I am bit confused now distinguishing between the Dependency property defined in the XAML.cs file as well as a CLR property defined in the view model which is bound to some property of a component
For example say, I have a textbox in MyPage.xaml. So I created a dependency property to bind the textbox text property in the MyPage.xaml.cs maybe some String. The next time, I created a viewModel MyPageViewModel.cs which implements the INotifyPropertyChanged interface and
created a CLR property there(String), which emits an event PropertyChanged when it changes or the property is set with a new value. So are these both the same? Is there any difference?
I have 3 questions
Is the Dependency Property same as CLR property which emits a PropertyChanged event when it changes?
Whether Dependency property is written in the view itself(MyPage.xaml.cs) or can it be included in the view
model(MyPageViewModel.cs)?
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?
Thanks in advance.

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.
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)
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.
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).

Related

How to apply Metadata from a ViewModel to the View in WPF with MVVM

I have a viewModel with properties like the following and a set of specific attributes used throughout the viewmodels.
public class MyViewModel : BaseModel
{
[StringLength(50), Required]
[SetLockedForExistingEntities]
public string FirstName { get ... set ... }
public bool IsInNewMode { get; }
}
Now I want to apply such metaData in a view in a consistent way. Like... If bound, set TextBox maxlength from the MaxLengthAttribute. If SetLockedForExistingEntitiesAttribute is set, disable the control in case viewModel is not in some 'New' Mode etc..
Is that doable/a good idea to do with a custom MarkupExtension that replaces "Binding" for VM Bindings? Or would it be better to use a Behavior (applied via attached property) which tries to apply anything it can from the bound ViewModel property to the control it is attached to?
Usage would be like
(A) Attached dependencyproperty that reads the binding from TextBox.Text and applies behaviors
<TextBox Text="{Binding Model.FirstName, ValidatesOnDataErrors=True}" "bb:MyBindingHelper.ApplyViewModelBehaviors="True" />
(B) Custom MarkupExtension that does all in one
<TextBox Text="{BindingWithModelBasedBehaviors Model.FirstName}" />
You could write a markup extension that gets the property from the datacontext and reads attributes.
That would be kind of complicated but you can get the property name of properties where the source changed event was raised.
That looks rather like validation to me.
You could implement inotifydataerrorinfo in a base viewmodel and write code there that validates properties using attributes.
That's how the code in this works:
https://gallery.technet.microsoft.com/scriptcenter/WPF-Entity-Framework-MVVM-78cdc204
That works by the view telling the viewmodel which property's value just passed to the viewmodel.
You can extend the method you use for raising property changed to pass the property name to the validation.
Or you could even do the check from a method called in the property setter before you set the value on a property and not set the value if the new one fails validation.
As a specific property fails validation in a particular way you could run an action.
The production code version of that app I linked also has a dictionary of predicates used as well as attributes. They could have code in them references and sets other viewmodel properties.

Why do ViewModels need to implement INotifyPropertyChanged or use Dependency Properties?

I've seen many Tutorials about the MVVM-Patern but I still don't get why I need to get a Dependency-Property or an INotiyfyPropertyChanged-Property if I want to send information from the ViewModel back to the View.
Dependency properties provide built in change notification for when a property changes which means WPF knows when a controls value has changed.
Your ViewModel types do not, by default, provide any mechanism for change notification so if they don't support either of these options how is the view supposed to know when a property in your viewModel has been changed?
You need your viewModel to use either of these options so that the view can be notified when a property value changes.
This means if a property value is changed in code, the user interface is updated and if a property is changed by user input your viewModel (and ultimately your model) is also updated to reflect these changes. (basically both sides of a binding require a way of communicating a property change to each other).
The INotifyPropertyChanged interface is the preferred method as it means your viewModels are not specific to WPF and can be used by other user interface technologies. also, dependency properties can only be used in types that derive from DependencyObject.
First: You do not need to use INotifyPropertyChanged or DependencyObject at all.
But, and this is the central point in using Binding, there is some Pub / Sub Mechanism in
the Binding, which is listening to those PropertyChanged events and doing the update
of the view in case a relevant property for Binding has changed.
Here is more information on that:
SO on how binding works
Pub Sub aka Publish Subscribe Pattern
INotiyfyPropertyChanged - This property we used in the viewmodel so that if there happens any changes in the UI this property will reflect those changes.

How to create a dependency property in Silverlight using MVVM?

let say there is a textbox and i want to control the visibility of this control using MVVM, is there a sample on how to do this? First create a dependency property then get it hooked up in the ViewModel. Thanks.
Typically, you wouldn't need to use a dependency property in this case. Dependency properties really only need to be implemented for things like controls themselves, not for determining behavior. Behavior, such as the visibility of an element, can be handled directly via data binding.
Your ViewModel would just have some property, and you'd bind the TextBox.Visibility property directly to the ViewModel property.
The one "sticky point" is that you often will want to have some type of IValueConverter that will convert from your property type to a Visibility enum.

Link between INotifyPropertyChanged and Databinding

I read this
Simple Binding of Data from code behind to XAML
What's the link between INotifyPropertyChanged and Databinding above not clear from the sample code.
You will want to review Data Binding in the MSDN documentation for a more clear description of how data binding is working in Silverlight and WPF. When you define a data binding declaratively in XAML, an instance of the Binding class is created that connects the properties of binding targets and data sources. It is this Binding class that is performing the monitoring and propagation of changes between the target of the binding and the data source.
While it is technically possible to bind to CLR objects that do not implement the INotifyPropertyChanged interface, it is definitely recommended that "for changes to the source object to propagate to the target, the source must implement the INotifyPropertyChanged interface. INotifyPropertyChanged has the PropertyChanged event, which tells the binding engine that the source has changed so that the binding engine can update the target value." See How Data Binding References are Resolved for further details.
if you have a piece of code that needs to update the UI and the UI is bound to a Poperty like in that example, INotifyPropertyChanged is how we can update the UI without having to do anything extra.
When you bind your property in xaml (XP) to property in code (CP), the binding contains link to object, which contains CP and the name of CP. If the object inherits INotifyPropertyChanged, binding system subscribes on PropertyChanged event and every single time it rises, binding system receives property-name string from propertyChangedEventArgs object and updates bindings for all XPs which are binded to CP with that name.

Dependency Properties on Controls

In WPF some properties of controls are dependency properties, others are normal properties.
Eg TextBox.SelectedText is a normal property and not a dependency property. I use MVVM and it happens often to me that I want to bind to some property, but I cant, because it is a normal property.
Can someone explain to me, what logic stands behind the decision whether a property is normal or a dependency property.
Also, can I work around this and somehow bind to the normal properties as if they were dependency properties?
Go through these links
When to use a WPF Dependency Property versus INotifyPropertyChanged
http://social.msdn.microsoft.com/forums/en-US/wpf/thread/65bf126f-e706-4d3e-8cc3-e0130a0ee6de
http://joshsmithonwpf.wordpress.com/2007/06/22/overview-of-dependency-properties-in-wpf/
WPF: What distinguishes a Dependency Property from a regular CLR Property?
How to set bindings on CLR Properties using DataResource
You will get better idea about what you are looking to find out
You can bind to normal properties, but if your property changes, your binding will not get notified. However, you can implement INotifyPropertyChanged in your classes and the binding will update your control automatically.

Resources