Databinding to non-ViewModel properties in MvvMCross - c#

I have an MvxListView that binds to a property on the ViewModel which is a List<MyClass>.
MyClass is a plain old object that has a boolean property named Completed that I've bound to the Checked property of a CheckedTextView in my list view item template.
When I click on the list view item, it invokes a command which calls a DoSomething(MyClass item) method. In the DoSomething method, I set the Completed property to its new value. However, because MyClass is not a ViewModel with RaisePropertyChanged properties, the checked property doesn't get updated in the user interface.
How would I accomplish data binding on this basic POCO to get the user interface to update when the Completed property changes?

How would I accomplish data binding on this basic POCO to get the user interface to update when the Completed property changes?
Xaml/C# style Data-Binding relies on INotifyPropertyChanged - without this the UI has no way to know that it needs to update.
So to get data-binding to work, your MyClass objects can't just be a POCO - it needs to implement INotifyPropertyChanged somehow - e.g. by inheriting from MvxNotifyPropertyChanged or by implementing INotifyPropertyChanged directly (e.g. see http://msdn.microsoft.com/en-us/library/vstudio/ms229614%28v=vs.100%29.aspx)
Aside: MvvmCross does also make other binding patterns possible beyond INotifyPropertyChanged - e.g. see INotifyChanged in FieldBinding in https://github.com/MvvmCross/MvvmCross/wiki/Databinding#rio - but this still requires something more than just POCOs for dynamically updating bindings.

Related

When and where to use NotifyPropertyChanged

Could someone explain the use of notify property changed and in which cases should I be using it?
For example:
I have in my silverlight application the domain data source which loads data and the event LoadedData where I set to some lists (List) the content of the entities from the domain context and bind the lists to the girds.
Do I need to use NotyfiPropertyChanged on the Lists?
Thanks,
I think you are getting the concepts slightly confused here...
There are two relevant notification interfaces for use with XAML Binding technologies.
INotifyCollectionChanged - notifies listeners when the collection of items changes (as in add/remove/replace/reorder actions).
INotifyPropertyChanged - notifies listeners that the content of an object has changed (as in values have been set and itself and other properties have changed).
In your case, if you want to notify that the contents of the List have changed, you need to use an INotifyCollectionChanged enabled collection to do that (i.e. not List - typically ObservableCollection).
If you wanted to notify that an item within the List has changed then the object type contained in the List should implement INotifyPropertyChanged.

MVVM Pattern, ObservableObject

Please, help me to understand one thing in the MVVM pattern:
For example, I need to display cities on a map.
In ViewModel I have ObservableCollection, that binded to a View ItemsSource.
ObservableCollection contains objects with type "City".
Must "City"-class be inherited from ObservableObject (I use MVVM Toolkit)? Or I should create a wrapper class, inherit it from ObservableObject, in ViewModel create new wrap-objects with data from "City"-objects and add them to the collection?
Thank you!
Assuming that your City class is in your model, and you actually need to know about changes to properties on the city object - then you should create a wrapper for it (i.e. CityViewModel). Your wrapper should listen to events that notify of any changes to the City class, and fire off the relevant Property Change notifications.
Model classes should be designed to fit with the model and should not change to suit your view - the point of having a ViewModel in the first place is to abstract your model from your view. The model should know nothing of the View.
If the properties of your City class dont change, or you dont care if they don change (and you are not a purist) then you could just expose it directly - without inheriting ObservableObject.
(Although I dont use MVVM toolkit, I cant see why in general you would need to inherit ObservableObject just because you are storing the City objects in an ObservableCollection).
The purist view however, is to wrap everything that you bind to and never expose anything from the model directly to the view.
ObservableCollection or ObservableObject has no relation with MVVM model. You can create a MVVM based application without ObservableCollection and ObservableObject (ObservableObject are used when you need to change the values of property of your class but if your application is readonly you dont even need it).
MVVM -
M-Model (business layer) , V-View (GUI), ViewModel- (Context of GUI).
When XAML works on binding. You must need a notification mechanism to notify GUI that something is changed. Now if a collection is changed means you added or removed an item from collection, you need to raise a notification which you dont need if you are working with ObservableCollection. Similarly, if your class City has a property Population which when changes need to notify GUI, that's why need to make an ObservableObject.
Hope it helps..

How to get notified when something changes in a WPF window?

I have an ObservableCollection that's binded to a WPF ListView, and all the values appear correct. But how can I get a notification when something that has a 2-way binding changes?
Should I use INotifyPropertyChanged just like in Winforms? Or are there better practices to do these?
I saw some people suggesting using dependency properties online, but not sure if that's what should do.
If the class I want to add a property is a DependencyObject, I generally add a DependencyProperty. If the class is a POCO (plain old clr objects), then I implement INotifyPropertyChanged.
In generall, all my business objects are POCOs and therefore I use INotifyPropertyChanged. In the WPF world, I mostly use DependencyObjects (view models, custom controls, UserControls...) and therefore they are DependencyProperties. An exception are ViewModels representing items (to be used as items in an items source). In this case I think DependencyProperties are not very practical (Because Equals() and GetHashCode() of DependencyObjects are sealed and DependencyObject is thread-dependent).
If your class already is a DependencyObject, using DependencyProperties may give you some nice advantages: You don't have to back every value, a powerfull inheritance system, default-values, property changed callbacks per property, value coercion ... (I like DependencyProperties probably more than other people them like :)
Conclusion:
Based on the title of your question: How to get notified when something changes in a WPF window?, my way would be to add a DependencyProperty and not a clr-property because the Window is a DependencyObject. By the way, Visual Studio has a nice Snippet to create DependencyProperties.
There are really two scenarios:
1) Notifying the UI when a piece of data changes-either in the ViewModel or a Model that is bound to some UI elements (usually due to a data binding). In this scenario you'd use INotifyPropertyChanged.
Example: you have a Person object that binds it's Name to a TextBox. Person needs to implement INotifyPropertyChanged and the appropriate code needs to be attached to the Name Property's setter.
2) Creating custom UI elements where you'd want data to be bound. In this case, you'd use custom dependency properties.
Example: you have a custom UI element that spins when a certain condition is met. So you create an IsSpinning dependency property that you can bind to your ViewModel's IsLoading property. The custom control then uses the IsSpinning property to modify its behavior.
I hope that was clear...
You are right. You can use INotifyPropertyChanged or you can implement dependency properties. Personally I prefer INotifyPropertyChanged, it's more light and easyer to implement than dependency property.
I've generally used INotifyPropertyChanged for my data objects.
DependencyProperties can only be implemented on framework elements I believe.
Edit: I take that back... DependencyProperties can only be implemented on DependencyObjects (A FrameworkElement is an example of that as it derives from UIElement which derives from Visual which derives from DependencyObject).
If you have a UserControl, you may wish to implement a Dependency Property so you can Bind that Property (in XAML) to some other property. You could not do this scenario with INotifyPropertyChanged.

easiest way to renew Datacontext binding in WPF

What is the fastest way to update my DataContext binding to my WPF usercontrol so that it shows changes in the object it is bound to in the view?
The best option is to make your DataContext object implement INotifyPropertyChanged. Make any collections implement INotifyCollectionChanged (ie: use an ObservableCollection<T> instead of List<T>, etc).
If you do this, then the bindings will automatically stay up to date, with no effort on your part.
Binding an ObservableCollection (which implements a specific interface) with objects that implement INotifyPropertyChanged will immediately show changes to their values in the front end or backend whenever you make changes, as long as the binding modes are set to two way binding.
This question here appears to be very similar.
Silverlight: How to force binding after setting the DataContext property
If you don't want to implement the INotifyProperty, you can use my answer and just set the datacontext again

How do I update an existing element of an ObservableCollection?

I have an instance of ObservableCollection bound to a WPF listbox with two separate data templates (one for display, one for editing). The data template for editing has a one-way binding on the textbox, and a Save button.
What changes do I need to make so that when I press the Save button (after putting the list item in edit mode), the value I change the textbox to replaces the value in the ObservableCollection (and the display)?
Items in your collection should be of type that implements INotifyPropertyChanged interface. This way your list box will be notified that property value in your single item object has changed. ObservableCollection raises CollectionChanged event only when collection changes (items added, removed, etc.)
Quote from the MSDN library article on ObservableCollection
To fully support transferring data
values from binding source objects to
binding targets, each object in your
collection that supports bindable
properties must implement an
appropriate property changed
notification mechanism such as the
INotifyPropertyChanged interface.
For change notification to occur in a binding between a bound client and a data source, your bound type should either:
Implement the INotifyPropertyChanged
interface (preferred).
Provide a change event for each
property of the bound type.
Do not do both.
Source: MSDN: INotifyPropertyChanged Interface
I've solved similar problem using BindingList<T> class.
It has ListChanged event fired both on collection and individual item change.
Introduced in .Net 3.5

Categories

Resources