user2190492
user2190492

Reputation: 1202

How to distinguish between Dependency Property change from inside the class, or outside

I'm creating a WPF Custom Control. The control is a time picker. It exists of a TextBox containing a string representing the time the user inputs (like 16:35). When that TextBox is focussed, a Popup opens, containing two separate TextBoxes for the hour and the minute for easy input.

enter image description here

The popup TextBoxes and the main field TextBox should be synchronized. By this I mean, when the user changes the hour by clicking the arrow keys, or typing in the small hour field, the main textbox (containing text 16:35) should be updated, and vice versa. The fields in the Popup are restricted to only accept [0-9] characters. When the main TextBox time string changes, string is parsed and the two fields in the Popup are updated. If the user types an invalid time string in the main TextBox and the control can not extract the hour and minute from it to update the Popup TextBoxes, then I just do nothing.

The arrow buttons in the popup are bound to commands.

I only use the class of the Custom control. I do not attach any DataContext and I only want to use dependency properties.

My control has multiple dependency properties, and the user-view that contains my control should use the following dependency property:

For the internal working, I also have a few more dependency properties:

Example of my problem:

When the user changes any field, the total control fields must be synchronized. So if the text in the hour field of the Popup changes, the main field's time string changes. I do this by using dependency property changed callbacks defined in the dependency property metadata. But the problem is that using this callbacks, you do not know if the change came from the control template (an action directly from the user) of from the class itself that sets a DP value). This causes vicious circles and you lose overview very soon. Its not that my program crashes, but problems occur like DP's are updated twice and that kind of unwanted behaviour.

  1. TextBoxText changed by user typing a timestring in it (12:45)
  2. DP callback is called because TextBoxText DP changes its value, so control wants to update TextBoxes in Popup
  3. TextBoxText string is parsed and DP Hour and Minute are set to a new value.
  4. DP Hour callback is called, and DP Minute callback is called.
  5. In this Hour and Minute DP callbacks, the TextBoxText must be updated -> causes a loop (see step 2). Because it doesn't distinguish changes from 'outside' (the user of view that uses the control) or from 'inside' (the control class that changes its own DP's).

How to solve this? Anyone who has experience with this or am I doing something wrong?

Upvotes: 2

Views: 237

Answers (1)

Bizhan
Bizhan

Reputation: 17085

This is how I handle it most of the time:

pseudocode:

callback(){
   if(flag){
      it's coming from program
   }
   else{
      it's coming from user
   }
}

button_event_handler(){
   flag = true
   do_stuff()
   flag = false
}

However there are other ways to do it if this is not applicable to your code.

For example in case of complex values like parts of date time, you can store the actual DateTime in a property which is bound to each of the controls through a converter. It must be injective or otherwise the whole thing will end up in a loop. By injective I mean each state of the updown controls must have only one state of the textbox and vice versa.

Upvotes: 1

Related Questions