Imagine a Control
is being created.
It has some DependencyProperties
and there are some properties which depend on the DependencyProperties
, but doesn't need to be seen or updated from the outside.
For example: Foo
is a DependencyProperty
(that can be both read and write from the outside) and Bar
is a common property that will be updated when (and only when) Foo
changes.
public class MyControl : Control
{
private static DependencyProperty FooProperty =
DependencyProperty.Register("Foo",
typeof(int),
typeof(MyControl),
new PropertyMetadata(FooChanged));
private static void FooChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
MyControl changedObject = d as MyControl;
changedObject.Bar++;
}
// The dependency property
public int Foo { get; set; }
// The property that is changed (only) when the dependency property changes
public int Bar { get; private set; }
}
However, Bar
's value is displayed in the screen (a Binding
is established in the control's template). But since Bar
is not a DependencyProperty
no notification is sent to say that it's value has changed.
I see two options to solve this issue (but I'm open to suggestions).
- Make my
Control
implementINotifyPropertyChanged
or
- Make
Bar
a readonlyDependencyProperty
What are the pros and cons of each approach? How should I proceed?
Is it a bad practice to implement INotifyPropertyChanged
on a Control
?
@EDIT
This questions was raised when I was creating a control that filters and displays a collection of games.
The data of this collection is "constant" (the games are loaded with the app and doesn't change to the end of the execution). However, the user can apply filters to this collection (for example, only displaying games that are in English)
As you can imagine, the filters are the Dependency Properties
, while the collection of games is a simple property, that I wasn't sure if I should turn into a ´DependencyProperty´ (since it would always be the same, only filtered according to the ComboBoxes
)
INotifyPropertyChanged
is typically implemented in the ViewModel, not the View.bar
andfoo
are. If you want to expose a calculated property which, by case, will be binded and displayed then go with aDependencyProperty
(think for example aboutActualWidth
). The point is that the property is not intended for visualization. If, instead, it's something that belongs only to visualization then it definitely must stay in the ViewModel (and yes, it's a bad practice to put it in the control).Control
...where to put it? If in ViewModel you then put a strong requirement on the data context associated with the control. If that's the case then you may introduce a local private ViewModel (especially if you expect more use cases) but it's not a general answer you can get without more context.