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.
Related
I am trying to show a ChromiumWebBrowser that navigates between local HTML files.
I set a binding to the Address property in my VM, and it works only in the initial value.
when I set the address in ViewModel binded property (navigating with custom buttons) browser does not update.
what am I missing here?
(in Snoop I can see the address indeed changes, but view is same).
Your ViewModel class must implement the INotifyPropertyChanged interface and call OnPropertyChanged whenever the ViewModel property is updated.
INotifyPropertyChanged Example
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 main window that contains two usercontrols.
The first usercontrol have a tabcontrol.How can I notify the second usercontrol when a tabitem is selected in the first usercontrol.
If you're using MVVM approach, you'll probably have bound SelectedIndex of your TabControl to a ViewModel property. In that case your second usercontrol will bind to the same (or some other) property of the ViewModel and will be notified through standard notification mechanisms (such as INotifyPropertyChanged or DependencyProperty etc.).
In case, you are not using ViewModels and coding directly behind your Window, you can listen to SelectionChanged event and update your second usercontrol therein.
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.
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.