I have a XAML-object (window-control) having his own-properties in the code-behind (in my case it has a property called 'FirstEditableDate' without any UI-binding).
I also have another XAML-object (user-control) with a property (also without UI) and I want to bind the other property to this property.
So, if the property of the (main)class is changing, the other property of the usercontrol is also changing.
How can I do this?
(see for examples my 'answer' below...)
You can implement the INotifyPropertyChanged interface on the Main class and have the usercontrol handle the PropertyChange event.
Related
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).
I have a wpf wpplication with a number of user controls in it. One of these controls has a property called ButtonsEnabled. This is a bool DependencyProperty in the user control. The property is bound to the IsEnabled property of a couple of buttons on that control.
This user control is used in the MainWindow. The MainWindow has a couple of view model objects in it called EocMonitor and ComMonitor. These both descend from an abstract base class that implements INotifyPropertyChanged. The ButtonsEnabled property on the UserControl is bound to the Status property using a multibinding and a class that implements IMultiConverter that I wrote.
The problem is that even though the PropertyChanged event is being raised when the Status property changes, the IMultiConverter is not being called after it is initially called, so the value of the ButtonsEnabled property is not changing. As a result, the buttons are not enabling.
What do I need to do to make this work?
I did an end-run around this problem as I am running out of time before we reach our code-freeze for this release. What I did was I added a ButtonsEnabled DepdendencyProperty to the MainWindow class and bound it to the user control's ButtonsEnabled property. I then added a PropertyChanged event handler in the MainWindow and and registered it with the DbMonitor and ComMonitor objects when they were created. I then wrote code in the PropertyChanged event handler to set the MainWindow's ButtonsEnabled properly.
Everything works and I'll worry about making the other approach work at some later time. Maybe.
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.
Is it possible to get/set the value of CaretIndex property of a TextBox control in viewmodel in wpf via Binding defined in view?
Thanks
You can not bind the property CaretIndex since it is not a DependencyProperty. It is a CLR
property that does not accept binding.
The issue here is how to get the CaretIndex of the TextBox control via the view model.
If you intent to get it directly by binding to the view model its impossible. As I posted in the previous answer its a CLR property and not a dependency property.
What can we do?
The best solution for that is to follow the steps:
Define attached property on the control via separate class.
Define a property in the view model and bind the attached property to the one in the view-model
Update the control property in the callback of the attached property changed event according to the new value received.
In this case, we still separate the view from the model.
I hope my answer helps you!
I have an object which has a property of type ObservableCollection<bool>. It is bound to a list of checkboxes on a form using TwoWay bindings. I would like to add a PropertyChanged notification to this so that if certain values are selected, some other ones get automatically deselected. Is there a way to do this?
The ObservableCollection.PropertyChanged event doesn't get triggered when a value in the collection gets changed and I'm using the MVVM design pattern.
You would need to use your own class that implements the INotifyPropertyChanged interface. You won't be able to use bool, but you can have a single property in your class that is that bool that you want.