Dependency property based on POCO property that already notifies - wpf

I have a dependency property exposed in my control that takes its value from another object that already implements INotifyPropertyChanged.
Is there any way to tell WPF to subscribe directly to this object, or do I have to plumb the change notifications myself?
Cheers

I'm may be unclear on your question, but you could do:
control.SetBinding(YourDependencyProperty, new Binding("YourProperty") { Source = poco });
You can also set Mode to TwoWay to pass values back to the POCO.

Related

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

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

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.

Can we update a source that is not DepencyProperty or not INotifyPropertyChanged compliant

I have a business object that comes from the core of the application. That object does not inherit from INotifyPropertyChanged. It contains some property that my XAML code bind to it.
I only want to update the properties not the UI dynamically (OneWayToSource style).
By example, if I change the text of a text box, the source item does not get updated.
It is a limitation of silverlight that if the object does not implement INotifyPropertyChanged or use DepencyProperties that the source of the binding cannot be updated?
The source property does not need to be a dependency property nor does the class that exposes it need to implement INotifyPropertyChanged.
If you have the binding on the TextBox set to use the TwoWay mode editing the text box should update the bound property even if it is a plain "vanila" property. Note by default the focus has to leave the TextBox in order for the binding to update.
If your business object has a set method on the property you want to update, then the value should be updated, provided the value you enter doesn't trigger an exception.
Not implementing INotifyPropertyChanged hinders just visual feedback.

WPF Collections and Databinding

I am new to WPF and trying to wrap my head around WPF's framework, what it does and does not do for you.
To clarify this, I would like to know what is the difference between this:
public List<MyCustomObject> MyCustomObjects
{
get { return (List<MyCustomObject>)GetValue(MyCustomObjectsProperty); }
set { SetValue(MyCustomObjectsProperty, value); }
}
public static readonly DependencyProperty MyCustomObjectsProperty =
DependencyProperty.Register("MyCustomObjects", typeof(List<MyCustomObject>),
typeof(Main), new UIPropertyMetadata(new List<MyCustomObject>()));
and this:
public ObservableCollection<MyCustomObject> MyCustomObjects { get; set; }
public Main ()
{
MyCustomObjects = new ObservableCollection<<MyCustomObject>();
}
Ok, we must put some order into things, there's a few concepts mixed in together here.
First of all, you're asking what the difference is between a field-backed property and a dependency property. Google would be your best friend, however I recommend this blog post by WPF's vanguard Josh Smith: Overview of dependency properties in WPF
In short: dependency properties support the richness that is WPF: Styling, animation, binding, metadata, and more.
Secondly, you're asking what the difference is between a List and an ObservableCollection. Well the latter provides change notifications (in the forms of events) on any change to the collection (addition, removal, change of order, clearing, etc.), and the former does not. You can read more about that here: The ObservableCollection Class
In short: ObservableCollection provides change notifications which are required for the UI to automatically reflect changes in the view model.
In addition to Aviad and Reed's answers, I would like to point out a serious bug in your first code sample :
public static readonly DependencyProperty MyCustomObjectsProperty =
DependencyProperty.Register("MyCustomObjects", typeof(List<MyCustomObject>),
typeof(Main), new UIPropertyMetadata(new List<MyCustomObject>()));
The new List<MyCustomObject>() used as the default value will be created only once, so by default all instances of your type will share the same List<MyCustomObject> instance, which is probably not what you want... The only sensible default value here is null
In the first case, you're setting up a Dependency Property containing a List<T> instance.
In the second, you're making a normal CLR property, but having it setup as an ObservableCollection<T>.
For WPF Data Binding, there are some differences here.
Typically, you want all of your properties in the DataContext (which is the object that, by default, things "bind" to) to either implement INotifyPropertyChanged or to be a Dependency Property. This lets the binding framework know when changes are made to that object. Normally, though, you'd only use a Dependency Property if your working with a custom control - it's usually a better idea to have your object to which your data bound be a separate class, assigned to the DataContext. (For details here, see Josh Smith on MVVM or my recent detailed post on MVVM...)
However, with a collection, you typically also want the binding system to know when the items within the collection change (ie: an item is added). ObservableCollection<T> handles this by implementing INotifyCollectionChanged.
By using the second approach (using an ObservableCollection<T>), your UI can tell when items were added or removed from the collection - not just when a new collection is assigned. This lets things work automatically, like a ListBox adding elements when a new item is added to your collection.
1:
You're using a dependency property to "tell" the framework when that property is changed. This will have the following consequences for your binding:
MyCustomObjects.Add(new MyCustomObject()); //Wont update the view through databinding
MyCustomObjects = new List<MyCustomObject>(); //Will update the view through databinding
You could gain the same databinding functionality by implementing INotifyPropertyChanged on which ever class exposes the property, but dependency properties a capable of much more than just notifying about changes. These are rather advanced features though, which you aren't likely to come across in your average joe app :)
2:
You're using an observable collection, which implements INotifyCollectionChanged for you, to tell the databinding whenever the content of the collection has changed. This will have the opposite consequences than #1:
MyCustomObjects.Add(new MyCustomObject()); //Will update the view through databinding
MyCustomObjects = new ObservableCollection<MyCustomObject>(); //Won't update the view through databinding

WPF Binding to ObjectDataProvider Method and detecting return value dependencies

I'm binding to a method using an ObjectDataProvider. The class which exposes this method contains an ObservableCollection of type T:INofifyChanged. My problem is that because the methods return value is dependent upon the value of it's ObservableCollection, i need the binding to be updated when the ObservableCollection changes in any way.
In short, the return value of the method is dependent on other factors and i want this method binding to refresh when it's dependencies change.
How can i let the bound control know when the methods return value will be different?
The ObservableCollection class exposes the CollectionChanged event which you could hook into.
You would possibly be better off using a ViewModel and handling the update via this though. Take a look at the MVVM pattern.

Resources