WPF ViewModel and View - wpf

I've been programming in WPF for a while now coming from Windows Forms. Because of this I've always been linking my View and ViewModel directly together by giving my controls in the View a name and use that name in the ViewModel to update my View.
Now I did some searching and found out that there is something called MVVM. I've been studying it for a week now and tried to make my application 'better'.
First, I started using binding with Dependency Properties like this:
Public Shared SelKlantProperty As DependencyProperty = DependencyProperty.Register("SelKlant", GetType(String), GetType(MainWindow))
Public Property SelKlant As String
Get
Return DirectCast(GetValue(SelKlantProperty), String)
End Get
Set(value As String)
SetValue(SelKlantProperty, value)
End Set
End Property
I now have about 50 Properties made like that and my code is getting big pretty fast of those. Also my ClassDiagram is filled with the Fields of the Public Shared DependencyProperty and Properties of the Public Property.
I'm wondering, is there an easier or much better way to bind View and ViewModel? Most of the Properties I use are to put Text in TextBoxes.

You don't need to create dependency properties for your view model properties - regular properties will suffice. You will however have to use dependency properties if you're going to bind to that property (for example, TextBox.Text is a dependency property - you wouldn't be able to bind to it if it wasn't). You can keep your properties as they were - just make sure you implement INotifyPropertyChanged.
Dependency properties have other uses other than just for data binding, but I won't elaborate as it's a very large subject and you can find in other resources. Other than that, you can read more on how to implement the MVVM pattern here. This page also includes examples where you can see that the viewmodel does not need to have any dependency properties defined.

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

Can I have a MVVM model inherited from an other model?

I have a ProductViewModel class which contains different properties.
Then I have a ProductDetailsViewModel class which inherit from ProducViewModel class. The reason I am doing it this way is in order to get correct binding environement and avoid duplication of properties from previous view.
I am allowed to do this or each ViewModel should be clearly isolated?
Through code I can acess the properties of the ProductViewModel class from ProductDetailsViewModel view but when I set the datacontext of my ProductDetailView to ProducDetailsViewModel class and bind properties URI for instance which is define inside the inherited class, binding seems not occurs.
Any idea ?
You can do this too, but i think maybe better would be to separate them and use Dependency Injection.
You create and interface for your ProductViewModel and implement it and then you inject this into your ProductDetailsViewModel.
MVVM + WPF + DI
MSDN DI
Yes this is fine, and I do this all the time in my WPF projects so it should just work. Some suggestions:
Can you check your output window when debugging the application. Are there any binding errors suggesting a mis-typed xaml binding?
Are you using any DataTemplates in xaml which bind to a specific type, e.g. ProductViewModel not ProductDetailsViewModel?
Does the base type (ProductViewModel) implement INotifyPropertyChanged?
Are all the properties in ProductViewModel and ProductSetailsViewModel raising the PropertyChanged event with directly typed string property name?
Best regards,

Delayed "rendering" of WPF/Silverlight Dependency Properties?

Is there a way to know the first time a Dependency Property is accessed through XAML binding so I can actually "render" the value of the property when needed?
I have an object (class derived from Control) that has several PointCollection Dependency Properties that may contain 100's or 1000's of points. Each property may arrange the points differently for use in different types shapes (Polyline, Polygon, etc - its more complicated then this, but you get the idea). Via a Template different XAML objects use TemplateBinding to access these properties. Since my object uses a Template I never know what XAML shapes may be in use for my object - so I never know what Properties they may or may not bind to. I'd like to only fill-in these PointCollections when they are actually needed.
Normally in .NET I'd but some logic in the Property's getter, but these are bypassed by XAML data binding.
I need a WPF AND Silverlight compatible solution.
I'd love a solution that avoids any additional complexities for the users of my object.
Update
One way that I've found to do this is using Value Converters. In my situation I had multiple point collections. There was a main dep. property that contained the usual shape of the data. Two alternate shapes were needed for reuse in other areas/contexts.
At first I had 3 dep. props. But, I could have just had one property (the usual shape) and used a value converted to transform the points into my other 2 desired shapes. Doing this I only make the one set of points in the control. The expense of transforming points to the secondary shapes is only incurred when used. Now my main control doesn't need to anticipate how data needs to look for every possible template thrown at the control - now its the template designers problem.
Update 2
Certainly INotifyPropertyChanged and regular properties are the recommended way to handle this.
You don't necessarily have to use dependency properties to enable data-binding. However, you then have to implement INotifyPropertyChanged if changes at the source should be propagated to the target of the binding. A "normal" .NET property is easy to lazy load perhaps like this:
PointCollection points
public PointCollection Points {
get {
return this.points ?? (this.points = CreatePoints());
}
}
PointCollection CreatePoints() {
// ...
}
I'm not sure how you can fit INotifyPropertyChanged into your control, but it sounds a bit strange that your control supplies data to other parts of the system. Perhaps you need to create a view-model containing the data that you then can let your control data-bind to.
If I paraphrase your question to
How do I get notified when dependency property is changed?
will this be correct? I draw this from your phrase "Normally in .NET I'd but some logic in the Property's getter, but these are bypassed by XAML data binding".
If I'm correct, then you can register your own property changed callback. It's always called. Doesn't matter who caused the change binding, style or trigger. The following code snippet is taken from MSDN Article "Dependency Property Callbacks and Validation":
public static readonly DependencyProperty CurrentReadingProperty =
DependencyProperty.Register(
"CurrentReading",
typeof(double),
typeof(Gauge),
new FrameworkPropertyMetadata(
Double.NaN,
FrameworkPropertyMetadataOptions.AffectsMeasure,
new PropertyChangedCallback(OnCurrentReadingChanged),
new CoerceValueCallback(CoerceCurrentReading)
),
new ValidateValueCallback(IsValidReading)
);
public double CurrentReading
{
get { return (double)GetValue(CurrentReadingProperty); }
set { SetValue(CurrentReadingProperty, value); }
}
Your takeaway here is OnCurrentReadingChanged() method. Hope this helps :).

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

DependencyProperty and DataBinding?

In WPF:
Can someone please explain the relationship between DependencyProperty and Databinding?
I have a property in my code behind I want to be the source of my databinding.
When does a DependencyProperty (or does it) come into play if I want to bind this object to textboxes on the XAML.
The target in a binding must always be a DependencyProperty, but any property (even plain properties) can be the source.
The problem with plain properties is that the binding will only pick up the value once and it won't change after that because change notification is missing from the plain source property.
To provide that change notification without making it a DependencyProperty, one can:
Implement INotifyPropertyChanged on the class defining the property.
Create a PropertyNameChanged event. (Backward compatibility.)
WPF will work better with the first choice.
What is the DependencyProperty?
The DependencyProperty class is one of the most important design bases hidden deep in the .Net Framework WPF.
This class is protected by sealed from the .NET Framework.
This property differs from the one-dimensional general property in that it not only stores field values, but also takes advantage of the various functions provided within the class.
Most importantly, there is a full foundation for data binding. You can also send notifications whenever you bind something.
DependencyProperty
Wpf Xaml Binding
It's already a late answer, but I'll introduce the results of my research.

Resources