Share via


UWP: How to handle changes of DependencyProperty

Last time we discussed how to create our own state trigger. In order to do it we made some extensions of “view model” class in order to get information about changes in state of the model. We declared a delegate and an event there and additionally we injected code which initiated external event handlers. But in many cases you cannot modify a class which you are going to use in your trigger and the class doesn’t have needed events as well. In this case you can check dependency properties there.

Starting with Windows 10 you can handle changes in dependency properties even if the class doesn’t have any special events for it. It’s possible thanks to RegisterPropertyChangedCallback (and UnregisterPropertyChangedCallback) method which was included to DependencyObject class. Thanks to this method you can provide an event handler which fires when selected DependencyProperty is changed. This method is very useful for UWP controls when you need to track changes in existing controls but we can utilize this method in our classes as well.

Let’s try to modify classes from the previous post.

 public enum StateEnum
{
 Loading,
 Loaded,
 Error
}
 
public class PageViewModel: DependencyObject
{
 public static readonly DependencyProperty StateProperty=DependencyProperty.Register("State",typeof(StateEnum), typeof(PageViewModel),new PropertyMetadata(null));
 
 public StateEnum State
 {
 get
 {
 return (StateEnum)GetValue(StateProperty);
 }
 set
 {
 SetValue(StateProperty, value);
 }
 }
 
 public void InitModel()
 {
 State = StateEnum.Loading;
 //load data
 State = StateEnum.Loaded; 
 }
}

You can see that I removed the delegate and the event and added a StateProperty dependency property. Right now code looks better and usually if you implement your own “view model” class you already have some dependency properties there and probably you should not change anything.

Of course, in order to work with dependency properties we use the SetValue and GetValue methods. We used standard approach there – created a wrapper property. It’s clear that all changes around DependencyProperty in UWP were implemented inside the SetValue method. It just executed all methods which were registered thanks to RegisterPropertyChangedCallback.

My state trigger will look different as well:

 public class DataTrigger: StateTriggerBase
{
 private PageViewModel model;
 
 public PageViewModel Model
 {
 get
 {
 return model;
 }
 set
 { 
 model = value;
 model.RegisterPropertyChangedCallback(PageViewModel.StateProperty, 
 new DependencyPropertyChangedCallback(ChangeState));
 }
 }
 
 private void ChangeState(DependencyObject obj, DependencyProperty pr)
 {
 SetActive(model.GetValue(PageViewModel.StateProperty).
 ToString().Equals(StateOfModel));
 }
 
 public string StateOfModel { get; set; }
}

You can see that code looks better right now. Pay special attention that we use PageViewModel object to call RegisterPropertyChangedCallback method.

So, if you don’t have all needed events, check existing dependency properties and in many cases you find all that you need.